Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: stretch.c
  3. *
  4. * Routines to stretch a glyph bitmap up to five times in the x direction
  5. * and an arbitrary number of times in the y direction. These limits are
  6. * the ones imposed by windows.
  7. *
  8. * Created: 7-Dec-1992 16:00:00
  9. * Author: Gerrit van Wingerden
  10. *
  11. * Copyright (c) 1992 Microsoft Corporation
  12. \**************************************************************************/
  13. #include "fd.h"
  14. // Since there are only four ways we can stretch in the x direction we use
  15. // tables to do our stretching. The tables index 2 to 3 bit quantities to
  16. // bytes or words that correspond to the stretched values of those quantities.
  17. // This is much faster than doing all the shifting neccesary to stretch those
  18. // quantities.
  19. BYTE ajStretch2[16] = { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 0xC0,
  20. 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF };
  21. BYTE ajStretch3B1[8] = { 0x00, 0x03, 0x1C, 0x1F, 0xE0, 0xE3, 0xFC, 0xFF };
  22. BYTE ajStretch3B2[16] = { 0x00, 0x01, 0x0E, 0x0F, 0x70, 0x71, 0x7E, 0x7F, 0x80,
  23. 0x81, 0x8E, 0x8F, 0xF0, 0xF1, 0xFE, 0xFF };
  24. BYTE ajStretch3B3[8] = { 0x00, 0x07, 0x38, 0x3F, 0xC0, 0xC7, 0xF8, 0xFF };
  25. WORD awStretch4[16] = { 0x0000, 0x0F00, 0xF000, 0xFF00, 0x000F, 0x0F0F, 0xF00F,
  26. 0xFF0F, 0x00F0, 0x0FF0, 0xF0F0, 0xFFF0, 0x00FF, 0x0FFF,
  27. 0xF0FF, 0xFFFF };
  28. WORD awStretch5W1[16] = { 0x0000, 0x0100, 0x3E00, 0x3F00, 0xC007, 0xC107,
  29. 0xFE07, 0xFF07, 0x00F8, 0x01F8, 0x3EF8, 0x3FF8,
  30. 0xC0FF, 0xC1FF, 0xFEFF, 0xFFFF };
  31. WORD awStretch5W2[16] = { 0x0000, 0x0300, 0x7C00, 0x7F00, 0x800F, 0x830F,
  32. 0xFC0F, 0xFF0F, 0x00F0, 0x03F0, 0x7CF0, 0x7FF0,
  33. 0x80FF, 0x83FF, 0xFCFF, 0xFFFF };
  34. BYTE ajStretch5B1[4] = { 0x00, 0x1F, 0xE0, 0xFF };
  35. /**************************************************************************\
  36. * void vEmboldenItalicizeLine
  37. *
  38. * Emboldens and italicizes a scan line.
  39. *
  40. * Created: 7-Dec-1992 16:00:00
  41. * Author: Gerrit van Wingerden
  42. *
  43. * Copyright (c) 1992 Microsoft Corporation
  44. \**************************************************************************/
  45. void vEmboldenItalicizeLine( BYTE *pjDst, // Destitnation scan line
  46. BYTE *pjSrc, // Source scan line
  47. BYTE *pjEnd, // End of source scan line
  48. LONG lShift, // Amount by which to shift
  49. UINT uiPixelWidth // Width of scan line in pixels
  50. )
  51. {
  52. BYTE jSrcItalic;
  53. BYTE jCarry = (BYTE) 0;
  54. BYTE jCarryBold = (BYTE) 0;
  55. for( ; pjSrc < pjEnd; pjDst++, pjSrc++ )
  56. {
  57. jSrcItalic = (BYTE) ( (*pjSrc >> lShift) | jCarry );
  58. *pjDst = (BYTE) ( jSrcItalic | ( jSrcItalic >> 1 ) | jCarryBold );
  59. // remember the lShift rightmost and mve them over to the left
  60. jCarry = (BYTE) ( *pjSrc << ( 8 - lShift ));
  61. jCarryBold = (BYTE) ( jSrcItalic << 7 );
  62. }
  63. if( ( (long) ( 8 - ( uiPixelWidth & 7l )) & 7l ) < lShift )
  64. {
  65. jSrcItalic = jCarry;
  66. *pjDst = (BYTE) ( jSrcItalic | ( jSrcItalic >> 1 ) | jCarryBold );
  67. jCarryBold = (BYTE) (jSrcItalic << 7 );
  68. if( ( uiPixelWidth & 0x7l ) == 0l )
  69. {
  70. *(++pjDst) = jCarryBold;
  71. }
  72. }
  73. }
  74. /**************************************************************************\
  75. * void vEmboldenLine
  76. *
  77. * Emboldens a scan line.
  78. *
  79. * Created: 7-Dec-1992 16:00:00
  80. * Author: Gerrit van Wingerden
  81. *
  82. * Copyright (c) 1992 Microsoft Corporation
  83. \**************************************************************************/
  84. void vEmboldenLine( BYTE *pjDst, // Destination scan line
  85. BYTE *pjSrc, // Source scan line
  86. BYTE *pjEnd, // End of dest scan line
  87. UINT uiPixelWidth // Width of scan line in pixels
  88. )
  89. {
  90. BYTE jCarry = (BYTE) 0;
  91. for( ; pjDst < pjEnd; pjDst++, pjSrc++ )
  92. {
  93. *pjDst = ( *pjSrc | (( *pjSrc >> 1 ) | jCarry ));
  94. jCarry = ( *pjSrc << 7);
  95. }
  96. if( (( uiPixelWidth << 1 ) & 7l ) == 0l )
  97. *pjDst = jCarry;
  98. }
  99. /**************************************************************************\
  100. * void vItalicizeLine
  101. *
  102. * Italicizes a scan line.
  103. *
  104. * Created: 7-Dec-1992 16:00:00
  105. * Author: Gerrit van Wingerden
  106. *
  107. * Copyright (c) 1992 Microsoft Corporation
  108. \**************************************************************************/
  109. void vItalicizeLine( BYTE *pjDst, // Destitnation scan line
  110. BYTE *pjSrc, // Source scan line
  111. BYTE *pjEnd, // End of source scan line
  112. LONG lShift, // Amount by which to shift
  113. UINT uiPixelWidth // Width of scan line in pixels
  114. )
  115. {
  116. BYTE jCarry = (BYTE) 0;
  117. for( ; pjSrc < pjEnd; pjDst++, pjSrc++ )
  118. {
  119. *pjDst = (( *pjSrc >> lShift ) | jCarry );
  120. jCarry = ( *pjSrc << ( 8 - lShift) );
  121. }
  122. if( ( (long) ( 8 - ( uiPixelWidth & 7l )) & 7l ) < lShift )
  123. *pjDst = jCarry;
  124. }
  125. /*************************************************************************\
  126. * VOID vStretchGlyphBitmap
  127. *
  128. * Stretches a bitmap in fontfile format ( collumns ) to a row format and
  129. * performs bold and italic simulations. This routine could be faster
  130. * by spliting it up into several special case routines to handle simulations
  131. * and or different widths or by inlining the italicizing or emboldening
  132. * routines. However, we hardly ever need to stretch bitmap fonts so it
  133. * was deemed better to have one, nice neat routine that takes up less
  134. * code than several routines that are overall faster.
  135. *
  136. *
  137. * Created: 7-Dec-1992 16:00:00
  138. * Author: Gerrit van Wingerden [gerritv]
  139. *
  140. * Copyright (c) 1992 Microsoft Corporation
  141. \**************************************************************************/
  142. VOID vStretchGlyphBitmap( BYTE *pjTarget, // Target bitmap
  143. BYTE *pjSourceBitmap, // Source bitmap
  144. BYTE *pjLineBuffer, // Scan line buffer
  145. UINT uiPixelWidth, // Width of bitmap in pixels
  146. UINT uiHeight, // Height of bitmap in bits
  147. UINT uiVertScale, // Vertical scaling factor
  148. UINT uiHorzScale, // Horizontal scaling factor
  149. UINT flSim ) // Simulation flags
  150. {
  151. BYTE *pjSource, *pjBufferBase, *pjScanEnd, *pjSimEnd;
  152. UINT uiScanDelta, uiNewWidth, uiNewWidthSim, cjEmpty, uiCurScan;
  153. LONG lShift;
  154. BYTE *pjDone = pjSourceBitmap + uiHeight;
  155. uiNewWidth = ( ( uiPixelWidth * uiHorzScale ) + 7 ) >> 3;
  156. pjSimEnd = pjLineBuffer + uiNewWidth;
  157. cjEmpty = 0;
  158. switch( flSim )
  159. {
  160. case (FO_SIM_ITALIC | FO_SIM_BOLD):
  161. // fall through to the italic case with one added to cxOffset
  162. case FO_SIM_ITALIC:
  163. {
  164. UINT cxOffset = ( uiHeight * uiVertScale - 1 ) / 2;
  165. if( flSim & FO_SIM_BOLD )
  166. cxOffset += 1;
  167. uiNewWidthSim = ( ( uiPixelWidth * uiHorzScale ) + cxOffset + 7 ) >> 3;
  168. uiCurScan = 0;
  169. lShift = cxOffset & (UINT) 7;
  170. cjEmpty = cxOffset >> 3;
  171. break;
  172. }
  173. case FO_SIM_BOLD:
  174. uiNewWidthSim = ( ( uiPixelWidth *uiHorzScale ) + 8 ) >> 3;
  175. break;
  176. default:
  177. uiNewWidthSim = uiNewWidth;
  178. break;
  179. }
  180. // output bytes generated per new scan line
  181. uiScanDelta = uiNewWidthSim * uiVertScale;
  182. for( ; pjSourceBitmap < pjDone; pjSourceBitmap += 1 )
  183. {
  184. // first stretch one scan line
  185. for( pjSource = pjSourceBitmap, pjBufferBase = pjLineBuffer;
  186. pjBufferBase < pjLineBuffer + uiNewWidth;
  187. pjSource += uiHeight )
  188. {
  189. switch( uiHorzScale )
  190. {
  191. case 1:
  192. // don't stretch just copy
  193. *pjBufferBase++ = *pjSource;
  194. break;
  195. case 2:
  196. // stretch first nibble
  197. *pjBufferBase++ = ajStretch2[ *pjSource >> 4];
  198. //stretch second nibble
  199. *pjBufferBase++ = ajStretch2[ *pjSource & 0xf];
  200. break;
  201. case 3:
  202. // first byte
  203. *pjBufferBase++ = ajStretch3B1[ *pjSource >> 5];
  204. // second byte
  205. *pjBufferBase++ = ajStretch3B2[ (*pjSource >> 2) & 0xf];
  206. // third byte
  207. *pjBufferBase++ = ajStretch3B3[ *pjSource &0x7];
  208. break;
  209. case 4:
  210. // I know this is strange but I didn't think about alignment
  211. // errors when I used word sized tables. So i had to hack it.
  212. // !!! later these tables should be writen to be byte tables.
  213. // [gerritv]
  214. // first nibble
  215. *pjBufferBase++ = ((BYTE*)(&awStretch4[ *pjSource >> 4]))[0];
  216. *pjBufferBase++ = ((BYTE*)(&awStretch4[ *pjSource >> 4]))[1];
  217. // second nibble
  218. *pjBufferBase++ = ((BYTE*)(&awStretch4[ *pjSource & 0xf]))[0];
  219. *pjBufferBase++ = ((BYTE*)(&awStretch4[ *pjSource & 0xf]))[1];
  220. break;
  221. case 5:
  222. // first word
  223. *pjBufferBase++ = ((BYTE*)(&awStretch5W1[ *pjSource >> 4]))[0];
  224. *pjBufferBase++ = ((BYTE*)(&awStretch5W1[ *pjSource >> 4]))[1];
  225. // second byte
  226. *pjBufferBase++ = ((BYTE*)(&awStretch5W2[ (*pjSource >> 1) & 0xf]))[0];
  227. *pjBufferBase++ = ((BYTE*)(&awStretch5W2[ (*pjSource >> 1) & 0xf]))[1];
  228. // third byte
  229. *pjBufferBase++ = ajStretch5B1[ *pjSource &0x3];
  230. break;
  231. }
  232. }
  233. // now copy stretched scan line uiVertScale times while making the bitmap byte aligned
  234. pjScanEnd = pjTarget + uiScanDelta;
  235. switch( flSim )
  236. {
  237. case FO_SIM_ITALIC:
  238. for( ; pjTarget < pjScanEnd; pjTarget += uiNewWidthSim )
  239. {
  240. vItalicizeLine( pjTarget + cjEmpty,
  241. pjLineBuffer,
  242. pjLineBuffer + uiNewWidth,
  243. lShift,
  244. uiPixelWidth * uiHorzScale );
  245. lShift -= ( uiCurScan++ & 0x1 );
  246. if( lShift < 0 )
  247. {
  248. lShift = 7;
  249. cjEmpty--;
  250. }
  251. }
  252. break;
  253. case ( FO_SIM_ITALIC | FO_SIM_BOLD ):
  254. for( ; pjTarget < pjScanEnd; pjTarget += uiNewWidthSim )
  255. {
  256. vEmboldenItalicizeLine( pjTarget + cjEmpty,
  257. pjLineBuffer,
  258. pjLineBuffer + uiNewWidth,
  259. lShift,
  260. uiPixelWidth * uiHorzScale );
  261. lShift -= ( uiCurScan++ & 0x1 );
  262. if( lShift < 0 )
  263. {
  264. lShift = 7;
  265. cjEmpty--;
  266. }
  267. }
  268. break;
  269. case FO_SIM_BOLD:
  270. // first embolden this scan line
  271. vEmboldenLine( pjTarget, pjLineBuffer, pjTarget + uiNewWidth, uiPixelWidth * uiHorzScale );
  272. pjBufferBase = pjTarget;
  273. pjTarget += uiNewWidthSim;
  274. for( ; pjTarget < pjScanEnd; pjTarget += uiNewWidthSim )
  275. memcpy( (PVOID) pjTarget, (PVOID) pjBufferBase, (size_t) uiNewWidthSim );
  276. break;
  277. case 0:
  278. // just copy the scan line uiVertScale times
  279. for( ; pjTarget < pjScanEnd; pjTarget += uiNewWidthSim )
  280. memcpy( (PVOID) pjTarget, (PVOID) pjLineBuffer, (size_t) uiNewWidthSim );
  281. break;
  282. }
  283. }
  284. }
  285. /***************************************************************************\
  286. * VOID vStretchCvtToBitmap
  287. *
  288. * Stretches a bitmap and performs bold and italic simulations.
  289. *
  290. * Created: 7-Dec-1992 16:00:00
  291. * Author: Gerrit van Wingerden
  292. *
  293. * Copyright (c) 1992 Microsoft Corporation
  294. \**************************************************************************/
  295. VOID
  296. vStretchCvtToBitmap
  297. (
  298. GLYPHBITS *pgb,
  299. PBYTE pjBitmap, // bitmap in *.fnt form
  300. ULONG cx, // unscaled width
  301. ULONG cy, // unscaled height
  302. ULONG yBaseline, // baseline from font file
  303. PBYTE pjLineBuffer, // preallocated buffer for use by stretch routines
  304. ULONG cxScale, // horizontal scaling factor
  305. ULONG cyScale, // vertical scaling factor
  306. ULONG flSim // simulation flags
  307. )
  308. {
  309. ULONG cxNew, cyNew, yBaselineNew;
  310. // compute new height, width, and baseline
  311. cxNew = cx * cxScale;
  312. cyNew = cy * cyScale;
  313. yBaselineNew = yBaseline * cyScale;
  314. switch( flSim )
  315. {
  316. case ( FO_SIM_ITALIC | FO_SIM_BOLD ):
  317. cxNew = cxNew + ( cyNew + 1 ) / 2;
  318. break;
  319. case FO_SIM_ITALIC:
  320. cxNew = cxNew + ( cyNew - 1 ) / 2;
  321. break;
  322. case FO_SIM_BOLD:
  323. cxNew += 1;
  324. break;
  325. case 0:
  326. break;
  327. }
  328. // glyphbits data
  329. pgb->sizlBitmap.cx = cxNew;
  330. pgb->sizlBitmap.cy = cyNew;
  331. pgb->ptlOrigin.x = 0l;
  332. pgb->ptlOrigin.y = -(LONG) yBaselineNew;
  333. RtlZeroMemory( pgb->aj, ( CJ_SCAN( cxNew )) * cyNew );
  334. vStretchGlyphBitmap( pgb->aj,
  335. pjBitmap,
  336. pjLineBuffer,
  337. cx,
  338. cy,
  339. cyScale,
  340. cxScale,
  341. flSim );
  342. }