Windows NT 4.0 source code leak
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.

591 lines
21 KiB

4 years ago
  1. /******************************Module*Header*******************************\
  2. * Module Name: ifi.txt
  3. *
  4. * Changes that went into ifi and ddi to optimize text
  5. *
  6. * Created: 19-Sep-1991 13:00:06
  7. * Author: Bodin Dresevic [BodinD]
  8. *
  9. * Copyright (c) 1990 Microsoft Corporation
  10. *
  11. *
  12. \**************************************************************************/
  13. -----------------------------------------------------------------------------
  14. a) define the notion of integer font realization:
  15. All char inc vectors for this particular font realization,
  16. as well as all info in
  17. the FD_DEVICEMETRICS structure is guaranteed to be integer. (fractional
  18. parts of all points and distances are zero).
  19. Clearly such fonts will be designed for writing horizontally
  20. or vertcally ONLY. To distinguish such fonts
  21. another field will be added to FD_DEVICEMETRICS ,
  22. FLONG flRealizedType;
  23. and the FDM_TYPE_INTEGER bit will be set in flRealizedType field if
  24. this particular realization of the font is an integer realization.
  25. Let me clarify this by an example:
  26. Suppose a tt font, which is designed as a 12 pt font in its notional space,
  27. is scaled to 24 pt. If all per glyph metrics info was integer for the
  28. original font at 12 pt, clearly it will stay integer for the rasterized
  29. images at 24 pt. (Everything will just get multiplied by two). For this
  30. realization the FDM_TYPE_INTEGER flag should be set.
  31. However if we scale THE SAME to 15pt (the scaling factor is 5/4),
  32. a glyph that originally had char inc vector of length 5, will
  33. after realization have fractional length of 5 * (5/4) = 6.25, and the
  34. FDM_TYPE_INTEGER flag should NOT be set for this realization
  35. We may add more accelerator flags to flRealizedType field later on,
  36. if we find it convenient.
  37. // FDM_TYPE_INTEGER // all char inc vectors are integer for this font realization
  38. // FDM_TYPE_ZERO_BEARINGS // all glyphs have zero a and c spaces
  39. // the following two features refer to all glyphs in this font realization
  40. // FDM_TYPE_CHAR_INC_EQUAL_BM_BASE // base width == cx for horiz, == cy for vert.
  41. // FDM_TYPE_MAXEXT_EQUAL_BM_SIDE // side width == cy for horiz, == cx for vert.
  42. -----------------------------------------------------------------------------
  43. b) wcFirst and wcLast reintroduced to IFIMETRICS. Font may of may
  44. not contain all unicode code points between first and last.
  45. If the font does
  46. not contain all the wchars betwenn first and last, the font
  47. will have FM_TYPE_DISCONNECTED bit set in the IFIMETRICS
  48. -----------------------------------------------------------------------------
  49. c) 32.32 changes yet to be explained
  50. -----------------------------------------------------------------------------
  51. d) to improve unicode -> handle mapping in the ifi font drivers
  52. and the device drivers as well should exercise the following behavior:
  53. a) IFI interface:
  54. The new form of the FdQueryMappings will be as follows:
  55. LONG
  56. FdQueryMappings (
  57. IN HFF hff,
  58. IN ULONG ulFont,
  59. IN ULONG ulMode,
  60. OUT PVOID *ppv
  61. );
  62. The only mode for this function will be FD_QUERY_GLYPHSET,
  63. to replace the old FD_QUERY_MAPPINGS mode.
  64. The function will return a pointer to a FD_GLYPHSET structure,
  65. defined below, that the font driver has allocated and WILL NOT MOVE.
  66. The result will be returned in *ppv. If succesfull the function
  67. returns the size of the FD_GLYPHSET structure, otherwise returns
  68. FD_ERROR = -1;
  69. The FD_QUERY_LIG_MAP mode will be deleted at least in this
  70. release of the interface.
  71. b) DDI interface changes
  72. DrvQueryFontTree will change as follows
  73. PVOID DrvQueryFontTree(
  74. IN DHPDEV dhpdev,
  75. IN ULONG iFace,
  76. IN ULONG iMode);
  77. Modes will be changed as follows
  78. QFT_UNICODE --> to be replaced by QFT_GLYPHSET
  79. QFT_LIGATURES --> to be deleted in this release
  80. QFT_KERNPAIRS --> stays as kirko noted
  81. The function will return a pointer to a FD_GLYPHSET structure,
  82. defined below, that the device driver has allocated and WILL NOT MOVE.
  83. The definition of the FD_GLYPHSET structure:
  84. typedef struct _WCRUN {
  85. WCHAR wcLow; // lowest character in run
  86. WCHAR wcHigh; // highest character in run
  87. HGLYPH *phg; // pointer to an array of (wcHigh-wcLow+1) HGLYPH's
  88. } WCRUN;
  89. The following accelerator here is used to save both memory and time:
  90. If phg is set to (HGLYPH *)NULL, for all wc's in this particular run
  91. the handle can be computed as simple zero extension:
  92. HGLYPH hg = (HGLYPH) wc;
  93. If phg is not NULL, memory pointed to by phg, allocated by the driver,
  94. WILL NOT MOVE.
  95. typedef struct _FD_GLYPHSET {
  96. SIZE_T cjThis; // size of this structure in butes
  97. FLONG flAccel; // accel flags, bits to be explained below
  98. ULONG cGlyphsSupported; // sum over all wcrun's of (wcHigh - wcLow + 1)
  99. ULONG cRuns;
  100. WCRUN awcrun[1]; // an array of cRun WCRUN structures
  101. } FD_GLYPHSET;
  102. // flAccel - accelerator flags for the engine to ease the
  103. // the task of binary searching through the ordered list of wcrun's:
  104. // to be explained below
  105. The array of WCRUN structures must be ordered in order to support binary
  106. searches. That is, the following expressions must all be true:
  107. 1. All the runs are valid
  108. for (0 <= i && i < pgs->cRuns)
  109. pgs->wcrun[i].wcLow < pgs->wcrun[i].wcHigh
  110. 2. The runs are well ordered
  111. for (0 <= i && i < pgs->cRuns-1)
  112. pgs->wcrun[i].wcHigh < pgs->wcrun[i+1].wcLow
  113. The flAccel bits are defined as follows
  114. (only one for now, may add more in the future or drop them alltogether.)
  115. #define GS_UNICODE_HANDLES
  116. If this bit is set, for ALL WCRUNS in this FD_GLYPHSET the
  117. handles are
  118. obtained by zero extending unicode code points of
  119. the corresponding supported glyphs, i.e. (hg = (HGLYPH) wc)
  120. In this architecture the font driver is trusted to provide tables
  121. that are well defined and will never change. The drivers are encouraged
  122. to share GLYPHSET structures and phg arrays between its own fonts
  123. whenever possible. The engine will "read only" this memory.
  124. It is assumed that for this release of the product,
  125. there is a unique glyph for each supported character. This means
  126. that we cannot support Ligatures or glyph variants that are
  127. not defined in the Unicode standard. (Of course, if an application
  128. comes with its own built in font with ligatures, it will be able
  129. to take advantage of it).
  130. In order to optimize speed vs. memory requirement and to reduce the
  131. number of runs in the glyphset, the font driver
  132. may lie to the engine that it supports some unicode code points,
  133. which strictly speaking are not supported in a font.
  134. (Example 80h-9fh in most of win3.0 bm fonts, which strictly speaking
  135. are not supported unicode code points, they are just rectangles)
  136. It is than the
  137. responsibility of the driver to substitute the default character
  138. itself for those glyhps that are really not supported.
  139. The engine will do
  140. the substitution by the default character for those glyphs
  141. that the driver admitted that it
  142. does not support.
  143. -----------------------------------------------------------------------------
  144. e) font driver should return the following information (which is needed
  145. by the DDI call FONTOBJ_vGetInfo):
  146. cGlyphsSupported Number of glyphs in the font
  147. cjMaxGlyph1 Size of largest glyph (GLYPHDATA) in 1 bit/pel
  148. cjMaxGlyph4 Size of largest glyph (GLYPHDATA) in 4 bit/pel
  149. cjMaxGlyph8 Size of largest glyph (GLYPHDATA) in 8 bit/pel
  150. cjMaxGlyph16 Size of largest glyph (GLYPHDATA) in 16 bit/pel
  151. cjMaxGlyph32 Size of largest glyph (GLYPHDATA) in 32 bit/pel
  152. flCaps Capabilities flags--any combination of:
  153. FO_DEVICE_FONT <-- this is known
  154. FO_OUTLINE_CAPABLE <-- we need this!!!
  155. cGlyphsSupported can be made part of the IFIMETRICS.
  156. The cjMaxGlyphXX need to be queried on a per-HFC basis. Driver should
  157. return cjMaxGlyphXX = 0 if resolution XX bits/pel is not supported for
  158. that font.
  159. !!! currently, there is no way to request a pel-resolution when opening
  160. a Font Context. I believe that different pel-resolutions of the
  161. same font at the same xfrom are different realizations of the font.
  162. Perhaps the FD_XXBIT flags can be added to the fl field of the
  163. CONTEXTINFO structure?
  164. We need to know on a per-font basis whether outlines are supported
  165. by the driver FOR THAT FONT. There is a usType field in IFIMETRICS
  166. that can take the value FM_DEFN_OUTLINE, FM_DEFN_BITMAP, or
  167. FM_DEFN_STROKE. If redefined as follow, we should be OK:
  168. FM_DEFN_BITMAP only bitmaps supported
  169. FM_DEFN_OUTLINE outlines in addition to bitmaps are supported
  170. FM_DEFN_STROKE ???
  171. Or better yet, maybe usType should become flType and can take any
  172. combination of:
  173. FM_DEFN_BITMAP
  174. FM_DEFN_OUTLINE
  175. (Thus allowing for fonts that support one, the other, or both!).
  176. -----------------------------------------------------------------------------
  177. f) A field equivalent to the Window's logfont.lfCharSet is needed...
  178. possibly in the IFIMETRICS. It should return:
  179. ANSI
  180. OEM
  181. SYMBOL
  182. SHIFTJIS
  183. UNICODE
  184. Update: this is now part of the proposed streamlined IFIMETRICS
  185. structure (usCharSet field). [GilmanW] 09-Mar-1992
  186. -----------------------------------------------------------------------------
  187. g) This is really a change in ddi, not ifi but it came as an integral part
  188. of the changes made to improve text perf.
  189. STROBJ_bEnum has changed
  190. BOOL STROBJ_bEnum
  191. (
  192. IN STROBJ * pso,
  193. OUT ULONG * pcgpos, // number of valid GLYPHPOS strucs in the engine's buffer
  194. OUT PGLYPHPOS *ppgpos, // place to store the pointer to the engine's buffer
  195. );
  196. This way we avoid unnecessary copy of the data over ddi, from the engine's
  197. buffer to the drivers buffer. Also saves some resources.
  198. Note that if the driver wants handles (rather than pointers) and positions,
  199. (SO_GLYPHHANDLES enum mode) there really is no need to enumerate,
  200. all the glyph in the string will arrive in the first enumeration batch.
  201. This saves some complexity in the driver.
  202. GLYPHPOS data structure will have to be changed as follows:
  203. typedef union _PGLYPHDATA_OR_PPATHOBJ
  204. {
  205. PGLYPHDATA pgd;
  206. PPATHOBJ ppo;
  207. }
  208. PGLYPHDATA_OR_PPATHOBJ;
  209. typedef struct _GLYPHPOS
  210. {
  211. HGLYPYH hg;
  212. PGLYPHDATA_OR_PPATHOBJ u;
  213. POINTL ptl;
  214. }
  215. GLYPHPOS, *PGLYPHPOS;
  216. If a device driver asks for handles (and positions) the pointer fields
  217. will not contain valid data and the driver is encouraged to use
  218. these fields a scratch pad, e.g. to store pointers to its
  219. internal cache, if it has one.
  220. We should get rid of GLYPHBITS structure and keep just GLYPHDATA
  221. structures. This is little bit dirty, but it is stupid and inefficient to have to
  222. rewrite valid pointers to glyphdata's in the engine cache by
  223. the same pointers that are just offseted by offsetof(GLYPHDATA, aulBMData[0])
  224. In GLYPHDATA structure the two points (TLI and BRE) should be replaced
  225. by rclInkedBox, this is consistent with the rest of our interfaces.
  226. -----------------------------------------------------------------------------
  227. h) STROBJ accelerators
  228. // flAccel flags for STROBJ
  229. // SO_FLAG_DEFAULT_PLACEMENT // defult inc vectors used to position chars
  230. // SO_HORIZONTAL // "left to right" or "right to left"
  231. // SO_VERTICAL // "top to bottom" or "bottom to top"
  232. // SO_REVERSED // set if horiz & "right to left"
  233. // or if vert & "bottom to top"
  234. // SO_ZERO_BEARINGS // all glyphs in the string have
  235. // zero a and c spaces in
  236. // the direction of writing
  237. // SO_CHAR_INC_EQUAL_BM_BASE // base == cx for horiz, == cy for vert.
  238. // this has to be true for all chars
  239. // in the string. the font does
  240. // not have to be fixed pich
  241. // SO_MAXEXT_EQUAL_BM_SIDE // side == cy for horiz, == cx for vert.
  242. // // this has to be true of all chars
  243. // in the string,
  244. // max ext = asc + desc in device coord
  245. typedef struct _STROBJ
  246. {
  247. ULONG cGlyphs; // # of glyphs to render
  248. FLONG flAccel;
  249. ULONG ulCharInc; // zero if fixed pitch font, else equal to increment
  250. RECTL rclBkGround; // bk ground rect of the string in device coords
  251. } STROBJ;
  252. // ulCharInc should be used only if it is non zero, in which case
  253. // represents the INTEGER length of the char inc vector of all
  254. // glyphs in the font. Notice that this parameter will be set to
  255. // zero even if the font is fixed pitch font with fixed FRACTIONAL
  256. // character increment (the engine will then do the additions and
  257. // rounding to integer device locations and store them into the
  258. // array of glyphpos structures.
  259. The way the accelerator flags could be used in the driver
  260. is as follows:
  261. #define SO_MASK \
  262. ( \
  263. SO_FLAG_DEFAULT_PLACEMENT | \
  264. SO_ZERO_BEARINGS | \
  265. SO_CHAR_INC_EQUAL_BM_BASE | \
  266. SO_MAXEXT_EQUAL_BM_SIDE \
  267. )
  268. #define SO_HORIZ_MASK (SO_MASK | SO_HORIZONTAL)
  269. #define SO_HORIZ_REVERSED_MASK (SO_HORIZ_MASK | SO_REVERSED)
  270. #define SO_VERT_MASK (SO_MASK | SO_VERTICAL)
  271. #define SO_VERT_REVERSED_MASK (SO_VERT_MASK | SO_REVERSED)
  272. the code could be something as follows:
  273. if (
  274. (pstro->flAccel == SO_HORIZ_MASK) &&
  275. (bEqual(&pstro->rclBkGround, prclOpaque) // passed to DrvTextOut
  276. )
  277. {
  278. do not have to pre blt the bk rectangle, can just tile
  279. bitmaps from left to right
  280. }
  281. if (
  282. (pstro->flAccel == SO_HORIZ_REVERSED_MASK) &&
  283. (bEqual(&pstro->rclBkGround, prclOpaque) // passed to DrvTextOut
  284. )
  285. {
  286. do not have to pre blt the bk rectangle, can just tile
  287. bitmaps from right to left
  288. }
  289. if (
  290. (pstro->flAccel == SO_VERT_REVERSED_MASK) &&
  291. (bEqual(&pstro->rclBkGround, prclOpaque) // passed to DrvTextOut
  292. )
  293. {
  294. do not have to pre blt the bk rectangle, can just tile
  295. bitmaps from TOP to bottom
  296. }
  297. e.t.c.
  298. So far, the engine had to provide all positions of all glyphs in the
  299. array of GLYPHPOS strctures. This is clearly redundant in the case when
  300. SO_HORIZONTAL or SO_VERTICAL flags are set. Clearly, in the SO_HORIZONTAL
  301. case, y coordiantes of all the glyphs are going to be the same, only
  302. x coordinate will vary from glyph to glyph. Therefore, it is enough
  303. to supply the correct y coordiante of the first glyph in the string,
  304. the rest of y coordiantes will be the same. The engine should not waste
  305. time writing the same y coordinate in cGlyph places, nor the device
  306. driver should waste time reading it from cGlyph places.
  307. Similar statements can be made about SO_VERTICAL case, except that
  308. in this case only y coords will alter, and the correct x coordinate
  309. will be provided only for the first glyph.
  310. Moreover, if SO_HORIZONTAL flag is set, and we are dealing
  311. with fixed pitch font (font for which all the glyphs have the same char
  312. increment vector), it is not necessary to even write the x positions
  313. to the array of glyphpos structures, if the the x postion of the first
  314. char in the string is provided, it will be easy for the driver to
  315. compute the rest of positions as
  316. x[n + 1] = x[n] + so.ulCharInc;
  317. (in SO_VERTICAL case the driver should do y[n + 1] = y[n] + so.ulCharInc;)
  318. -----------------------------------------------------------------------------
  319. i) In BMFD, the PANOSE number values are hacked. A reasonable attempt
  320. was made to synthesize these numbers, but the FONTMETRICs available
  321. in Win 3.0 font files are insufficient to derive these numbers on the
  322. fly. By rights, these numbers should be assigned by the font designer
  323. and placed in the file.
  324. However, since they are NOT available in the Win 3.0 file format and
  325. we are contrained from modifying this format, I propose the following:
  326. 1) A flag be added to IFIMETRICS that indicates the validity of the
  327. PANOSE number; i.e., whether the mapper should bother to look at
  328. the PANOSE number or not.
  329. 2) The mapper penalizes a font if the PANOSE number is not usable.
  330. This is not only applicable to BMFD, but also to any other font technology
  331. which does not currently provide PANOSE numbers but for which compatibilty
  332. with NT is desired.
  333. -----------------------------------------------------------------------------
  334. j) new call added to ifi interface. Only tt driver should ever return
  335. success from this call. All other drivers should support this call but
  336. only as a stub
  337. { return FD_ERROR; }
  338. This function is added to ifi interface to support GetFontData true
  339. type api. this is excert from ttfd\fd_query.c:
  340. /******************************Public*Routine******************************\
  341. *
  342. * FdQueryTrueTypeTable
  343. *
  344. * copies cjBytes starting at dpStart from the beginning of the table
  345. * into the buffer
  346. *
  347. * if pjBuf == NULL and the caller is asking how big a buffer
  348. * is needed to store the info from the offset dpStart to the table
  349. * specified by ulTag to the end of the table
  350. *
  351. * if pjBuf != 0 the caller wants no more than cjBuf bytes from
  352. * the offset dpStart into the table copied into the
  353. * buffer.
  354. *
  355. * if table is not present or if dpScart >= cjTable 0 is returned
  356. *
  357. * tag 0 means that the data has to be retrieved from the offset dpStart
  358. * from the beginning of the file. The lenght of the whole file
  359. * is returned if pBuf == nULL
  360. *
  361. * History:
  362. * 09-Feb-1992 -by- Bodin Dresevic [BodinD]
  363. * Wrote it.
  364. \**************************************************************************/
  365. LONG
  366. FdQueryTrueTypeTable
  367. (
  368. IN HFF hff,
  369. IN ULONG ulFont, // always 1 for version 1.0 of tt
  370. IN ULONG ulTag, // tag identifying the tt table
  371. IN PTRDIFF dpStart, // offset into the table
  372. IN ULONG cjBuf, // size of the buffer to retrieve the table into
  373. OUT PBYTE pjBuf // ptr to buffer into which to return the data
  374. )
  375. -----------------------------------------------------------------------------
  376. k) [GilmanW] 09-Mar-1992
  377. I have a requirement to return to the control panel a string describing
  378. the font file. This string is typically in the non-resident names table
  379. in the (DOS) EXE header. If that is not available, the facename is an
  380. acceptable substitute.
  381. I believe this needs to be part of the IFI functionality since it
  382. should not be the responsibility of the engine to determine the contents
  383. of a font file. Whenever possible, the engine should avoid poking around
  384. in the internal formats of the font driver (Win 3.1's exposure of
  385. TrueType not withstanding).
  386. Currently, there is not entry point that can return information on a
  387. per font file (i.e., per HFF) basis. Therefore, I propose the following:
  388. LONG
  389. FdQueryFontFile (
  390. HFF hff, // strings from this font file
  391. ULONG ulMode, // indentifies type of string
  392. ULONG cjBuf, // number of BYTEs to copy to buffer
  393. PULONG pulBuf // pointer to buffer
  394. );
  395. Routine description:
  396. --------------------
  397. A function to query per font file information. In other words,
  398. information associated with a font file that is independent of
  399. the faces (ulFont) and font contexts (HFC).
  400. Parameters:
  401. -----------
  402. hff Handle to a font file.
  403. ulMode This is a 32-bit number that must be one of the following
  404. values:
  405. Allowed ulMode values:
  406. ----------------------
  407. FD_QUERY_DESCRIPTION--returns a UNICODE string that describes
  408. the contents of the font file.
  409. cjBuf Maximum number of BYTEs to copy into the buffer. The
  410. driver will not copy more than this many BYTEs.
  411. This should be zero if pulBuf is NULL.
  412. pulBuf Pointer to the buffer to receive the data
  413. If this is NULL, then the required buffer size
  414. is returned as a count of BYTEs. Notice that this
  415. is a PULONG, to enforce 32-bit data alignment.
  416. Return value:
  417. -------------
  418. Number of BYTEs copied into the buffer. If pulBuf is NULL,
  419. then the required buffer size (as a count of BYTEs) is returned.
  420. FD_ERROR is returned if an error occurs.
  421. -----------------------------------------------------------------------------
  422. l) FdQueryGlyphBitmaps
  423. In the description of the parameters, it is stated that if hglyph is
  424. zero (and some other conditions are met), then the function will return
  425. the minimum buffer size needed to get any glyph. This should be changed
  426. to hglyph is HGLYPH_INVALID. (HGLYPH_INVALID is no longer 0).
  427. -----------------------------------------------------------------------------
  428. m)
  429. -----------------------------------------------------------------------------
  430. n)