Source code of Windows XP (NT5)
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.

514 lines
17 KiB

  1. // xrcreslts.c
  2. // James A. Pittman
  3. // Jan 7, 1999
  4. // A container object to hold the results of recognition.
  5. // This is currently used by Inferno, MadCow, and Famine.
  6. #ifndef _XRCRESLTS_
  7. #define _XRCRESLTS_
  8. #define MAXMAXALT 32
  9. // Spped Accuracy tradeof values
  10. #define HWX_MIN_SPEED 0
  11. #define HWX_MAX_SPEED 100
  12. #ifdef UNDER_CE
  13. #define HWX_DEFAULT_SPEED 50
  14. #else
  15. #define HWX_DEFAULT_SPEED 0
  16. #endif
  17. #define PHRASE_GROW_SIZE 4
  18. #define NOT_RECOGNIZED "\a"
  19. #define BASELIMIT 700 // scale ink to this guide hgt if we have a guide
  20. #define MAX_SCALE 10 // We will not scale more than this.
  21. #define MAX_SEG 5 // maximum number of segmentations to resolve among
  22. #define MAX_SEG_WORD 5 // maximum number of wordmaps in a segmentation
  23. #ifdef __cplusplus
  24. extern "C"
  25. {
  26. #endif
  27. typedef struct tagWORDMAP WORDMAP;
  28. typedef struct tagLATINLAYOUT
  29. {
  30. // the first 4 fields are y-values for 4 lines relative to the bounding rect of ink
  31. // see the functions AbsoluteToLatinLayout() and LatinLayoutToAbsolute() for details
  32. short iBaseLine;
  33. short iMidLine;
  34. short iAscenderLine;
  35. short iDescenderLine;
  36. // the next 4 fields indicate which of the previous 4 are computed
  37. unsigned char bBaseLineSet;
  38. unsigned char bMidLineSet;
  39. unsigned char bAscenderLineSet;
  40. unsigned char bDescenderLineSet;
  41. } LATINLAYOUT;
  42. // The XRCRESULT object describes a single alternative interpretation of the ink.
  43. // There are 2 types: phrase and word. Both have a string and a cost.
  44. // Word XRCRESULT objects have a 0 cWords and a NULL pMap.
  45. // Phrase XRCRESULT objects have pMap pointing to an array of word mappings,
  46. // with the count of mappings in cWords. The PenWin API represents this
  47. // with an HRCRESULT.
  48. typedef struct tagXRCRESULT
  49. {
  50. unsigned char *szWord; // we use malloc for this string/phrase
  51. int cost; // 0 for perfect match, intmax for no match, neg numbers meaningless
  52. unsigned int cWords; // 0 in word mode, count of space delimited words in panel mode
  53. DWORD iLMcomponent; // Portion of LM generating this result
  54. WORDMAP *pMap; // NULL in word mode, valid in panel mode.
  55. void *pXRC; // Pointer to the xrc.
  56. } XRCRESULT;
  57. // The ALTERNATES object represents a set of alternative results for the
  58. // same ink. It has a count of alternates, and an array of XRCRESULT objects.
  59. // The array is in-line, with a length of MAXMAXALT. The alternates stay sorted
  60. // in increasing cost order. This is not represented in the PenWin API.
  61. // The users code, an implementation of HRC, should probably include an ALTERNATES
  62. // object in-line. On initialization the field cAlt should be zeroed.
  63. // Use RCRESALTInsert() to insert answers into the list of alternates.
  64. typedef struct tagALTERNATES
  65. {
  66. unsigned int cAlt; // how many (up to 10) actual answers do we have
  67. unsigned int cAltMax; // I can use this to say "I only want 4". !!! should be in xrc
  68. XRCRESULT aAlt[MAXMAXALT]; // The array of XRCRESULT structures
  69. LATINLAYOUT all[MAXMAXALT]; // baseline stuff for each alternate
  70. int iConfidence; //Contains the confidence level
  71. } ALTERNATES;
  72. // The WORDMAP contains a description of a word within the phrase
  73. // (the start index and the length), and a ALTERNATES to hold the alternative
  74. // results for this word. This is not represented in the PenWin API.
  75. typedef struct tagWORDMAP
  76. {
  77. unsigned short start; // start of the word in the phrase
  78. unsigned short len; // len of word in the phrase
  79. int cStrokes; // Count of strokes in this word
  80. int *piStrokeIndex; // Stroke indexes for this word
  81. ALTERNATES alt; // alternates for the word (only)
  82. } WORDMAP;
  83. // The XINKSET is the struct pointed to by an HINKSET.
  84. // It contains a counted array of INTERVALs, describing a (sub)set
  85. // of the ink in an HRC. The INTERVAL struct is defined in penwin.h
  86. typedef struct tagXINKSET
  87. {
  88. unsigned int count;
  89. INTERVAL interval[1];
  90. } XINKSET;
  91. // Verifies that the count of alternates is between 0 and 10 (inclusive).
  92. // Verifies that each live alternate has a non-NULL szWord.
  93. typedef struct tagANSWER_SET
  94. {
  95. ALTERNATES *pAlternates;
  96. int capSegments;
  97. int cAnsSets;
  98. } ANSWER_SET;
  99. // place holders for segmentation and SegCol structures
  100. typedef struct tagSEGMENTATION SEGMENTATION;
  101. typedef struct tagSEG_COLLECTION SEG_COLLECTION;
  102. // structure representing a single word alternate
  103. typedef struct tagWORD_ALT
  104. {
  105. unsigned char *pszStr; // CP1252 string
  106. int iCost; // cost assigned to the string by the recognizer
  107. LATINLAYOUT ll;
  108. }
  109. WORD_ALT;
  110. // structure representing a single word alternate list
  111. typedef struct tagWORD_ALT_LIST
  112. {
  113. int cAlt; // number of alternates
  114. WORD_ALT *pAlt; // list of alternates
  115. }
  116. WORD_ALT_LIST;
  117. // structure describing the set of features for a word map
  118. typedef struct tagWORD_FEAT
  119. {
  120. RECT rect;
  121. int cSeg;
  122. int iInfernoScore; // score inferno assign to Top1 of wordmap
  123. int iInfernoUnigram; // unigram value for Inferno's Top1 of wordmap
  124. int bInfTop1Supported; // Is inferno's Top1 word supported
  125. int iInfCharCost;
  126. int iInfAspect;
  127. int iInfHeight;
  128. int iInfMidLine;
  129. int iInfRelUni;
  130. int iInfRelBi;
  131. int iBearScore; // score Bear assign to Top1 of wordmap
  132. int iBearUnigram; // unigram value for Bear's Top1 of wordmap
  133. int bBearTop1Supported; // Is Bear's Top1 word supported
  134. int iBearCharCost;
  135. int iBearAspect;
  136. int iBearHeight;
  137. int iBearMidLine;
  138. int iBearRelUni;
  139. int iBearRelBi;
  140. int bIdentical; // are Inferno and Bear's output identical
  141. }
  142. WORD_FEAT;
  143. // structure representing a single word map (an ink chunk hypothesized to be a word)
  144. typedef struct tagWORD_MAP
  145. {
  146. int cStroke; // number of strokes
  147. int *piStrokeIndex; // list of stroke IDs (Frame IDs)
  148. WORD_ALT_LIST *pInfernoAltList; // alt list produced by inferno
  149. WORD_ALT_LIST *pBearAltList; // alt list produced by bear
  150. WORD_ALT_LIST *pFinalAltList; // final alt list
  151. int iConfidence; // confidence value assigned to this word
  152. WORD_FEAT *pFeat; // word map features used for segmentation
  153. }
  154. WORD_MAP;
  155. // structure describing the set of features for a segmentation.
  156. typedef struct tagSEG_FEAT
  157. {
  158. BOOL bInfernoTop1; // is this Inferno 's Top1 segmentation
  159. BOOL bBearTop1; // is this Bear 's Top1 segmentation
  160. int iSort1; // Sort criteria 1, currently for USA = cWord
  161. int iSort2; // Sort criteria 2, currently for USA = Avg. Inferno score
  162. }
  163. SEG_FEAT;
  164. // structure describing a particular segmentation of a chunk of ink into word_map(s)
  165. typedef struct tagSEGMENTATION
  166. {
  167. int cWord; // # of word maps
  168. WORD_MAP **ppWord; // list of wordmaps
  169. int iScore; // score assigned to this segmentation by
  170. // the segmentation classifier. Ranges from 0-0xFFFF
  171. SEG_FEAT *pFeat; // Segmentation feature vector
  172. SEG_COLLECTION *pSegCol; // the SegCol that this segmentation belongs to
  173. }
  174. SEGMENTATION;
  175. // structure describing all the possible segmentations of a chunk of ink referred to as a
  176. // segmentation set
  177. typedef struct tagSEG_COLLECTION
  178. {
  179. int cSeg; // # of possible segmenatations
  180. SEGMENTATION **ppSeg; // list of possible segmentations
  181. }
  182. SEG_COLLECTION;
  183. // structure describing a whole piece of ink as a number of seg_set (s)
  184. typedef struct tagLINE_SEGMENTATION
  185. {
  186. int iyDev; // yDev for the whole ink line
  187. int cSegCol; // # of SegCols
  188. SEG_COLLECTION **ppSegCol; // list of SegCols
  189. int cWord; // # of wordmaps constiuting the seg_set segmentations
  190. WORD_MAP **ppWord; // list of word maps constiuting the seg_set segmentations
  191. }
  192. LINE_SEGMENTATION;
  193. // structure used in Word breaking; similar to wordmap but got rid of unused entries.
  194. typedef struct tagWORDINFO
  195. {
  196. int cStrokes; // Count of strokes in this word
  197. int *piStrokeIndex; // Stroke indexes for this word
  198. ALTERNATES alt;
  199. }
  200. WORDINFO;
  201. // line structure
  202. typedef struct tagINKLINE
  203. {
  204. DWORD dwCheckSum;
  205. BOOL bRecognized;
  206. RECT rect;
  207. int cStroke;
  208. int cPt;
  209. POINT **ppPt;
  210. int *pcPt;
  211. GLYPH *pGlyph;
  212. LINE_SEGMENTATION *pResults;
  213. __int64 Mean;
  214. __int64 SD;
  215. }INKLINE;
  216. // line breaking structure
  217. typedef struct tagLINEBRK
  218. {
  219. int cLine;
  220. INKLINE *pLine;
  221. RECT Rect;
  222. }
  223. LINEBRK;
  224. #ifndef NDEBUG
  225. extern void ValidateALTERNATES(ALTERNATES *pAlt);
  226. #endif
  227. // Inserts a new word and its cost into the set of alternates.
  228. // The alternates remain in sorted order.
  229. extern int InsertALTERNATES(ALTERNATES *pAlt, int cost, unsigned char *word, void *pxrc);
  230. // Initializes a XRCRESULT object to represent a phrase.
  231. // The caller passes in a vector of pointers to ALTERNATES, representing
  232. // the sequence of words and their alternates. We steal them into
  233. // a vector of WORDMAP structs, and set up an XRCRESULT object
  234. // to own that vector of maps.
  235. // If an ALTERNATES object contains 0 answers, we insert "???" into the
  236. // phrase string, and in the word map we set the start and len fields
  237. // to refer to the "???".
  238. // We assume the caller passes at least 1 ALTERNATES, even though
  239. // it might have 0 answers.
  240. // Should the symbol be something special for "???".
  241. // Currently this version handles isolated periods and commas
  242. // correctly (they do not get a space before them). This is
  243. // to accomodate the current MadCow, which handles periods and
  244. // commas separately.
  245. // This should probably change to init (rather than malloc) an alt set
  246. // to have 1 result.
  247. extern int RCRESULTInitPhrase(XRCRESULT *pRes, ALTERNATES **ppWords, unsigned int cWords, int cost);
  248. // Sets the backpointers in all XRCRESULT objects within and ALTERNATES object,
  249. // including any contained within word mappings.
  250. //extern void SetXRCALTERNATES(ALTERNATES *pAlt, void *pxrc);
  251. // A destruction function that should only be used by an HRC destroying
  252. // the result objects that it owns. The PenWin function DestroyHRCRESULT()
  253. // is a no-op, since the result objects are internal to larger data structures.
  254. extern void ClearALTERNATES(ALTERNATES *pAlt);
  255. // Truncates the alt list to cAltmax, From cAltMax onwards: Does what ClearALTERNATES
  256. // Only intended for WORD ALTERNATES
  257. extern void TruncateWordALTERNATES(ALTERNATES *pAlt, unsigned int cAltMax);
  258. // Frees the stroke index array associated with a wordmap.
  259. void FreeIdxWORDMAP(XRCRESULT *pMap);
  260. // Add a stroke to the wordmap checking for duplicates and maintaining the a sorted list
  261. extern void AddThisStroke(WORDMAP *pMap, int iInsertStroke);
  262. // Locates WORDMAP under a specified result phrase based on the word position and length.
  263. extern WORDMAP *findWORDMAP(XRCRESULT *pRes, unsigned int iWord, unsigned int cWord);
  264. // Locates WORDMAP under a specified phrase result that contains a specified word result.
  265. extern WORDMAP *findResultInWORDMAP(XRCRESULT *pPhrase, XRCRESULT *pWord);
  266. extern WORDMAP *findResultAndIndexInWORDMAP(XRCRESULT *pPhrase, XRCRESULT *pWord, int *pindex);
  267. // Copy word maps into an xrCresult
  268. extern BOOL XRCRESULTcopyWordMaps(XRCRESULT *pRes, int cWord, WORDMAP *pMap);
  269. // Returns an array of RES pointers, one for each alternative interpretation of the
  270. // same word. The word is designated by RES object, start index, and letter count.
  271. // We return the pointers in ppRes, and return the count.
  272. // We only do whole words, so if the caller requests a substring that is not a word,
  273. // we return 0. If the word is the special marker "???" meaning the recognizer could
  274. // not produce interpretations, we return 0.
  275. extern int RCRESULTWords(XRCRESULT *pRes, unsigned int iWord, unsigned int cWord, XRCRESULT **ppRes, unsigned int cRes);
  276. // Returns (in a buffer provided by the caller) the "symbols" of the
  277. // word or phrase represented by pRes. Symbols are 32 bit codes.
  278. // Here the null byte at the end of a string is part of the string and
  279. // is copied into the symbol value array if there is room.
  280. // Returns the number of symbols inserted.
  281. extern int RCRESULTSymbols(XRCRESULT *pRes, unsigned int iSyv, int *pSyv, unsigned int cSyv);
  282. // Translates an array of symbols into an ANSI (codepage 1252) string.
  283. // This and SymbolToUnicode() below both translate until either cSyv is
  284. // exhausted or until they hit a NULL symbol or a NULL character.
  285. // The both return the count of symbols translated in *pCount.
  286. // Both return 1 if successful, or 0 if they encountered something
  287. // that could not be translated.
  288. extern int SymbolToANSI(unsigned char *sz, int *pSyv, int cSyv, int *pCount);
  289. // Translates an array of symbols into a Unicode string.
  290. extern int SymbolToUnicode(WCHAR *wsz, int *pSyv, int cSyv, int *pCount);
  291. // Backward compatibility.
  292. // These 2 functions exist to support the old API.
  293. extern int ALTERNATESString(ALTERNATES *pAlt, char *buffer, int buflen, int max);
  294. extern int ALTERNATESCosts(ALTERNATES *pAlt, int max, int *pCost);
  295. // Creates an InkSet to represent the part of pGlyph included within
  296. // a specified WORDMAP.
  297. extern XINKSET *mkInkSetWORDMAP(GLYPH *pGlyph, WORDMAP *pMap);
  298. // Creates an InkSet to represent the part of pGlyph included
  299. // within a specified word within a phrase.
  300. extern XINKSET *mkInkSetPhrase(GLYPH *pGlyph, XRCRESULT *pRes, unsigned int iWord, unsigned int cWord);
  301. // given a main glyph and a wordmap,
  302. // this function returns a pointer to glyph representing the word only
  303. extern GLYPH *GlyphFromWordMap (GLYPH *pMainGlyph, WORDMAP *pMap);
  304. extern GLYPH *GlyphFromNewWordMap (GLYPH *pMainGlyph, WORD_MAP *pMap);
  305. // given a main glyph and set of strokes,
  306. // this function returns a pointer to glyph representing only those strokes
  307. extern GLYPH *GlyphFromStrokes(GLYPH *pMainGlyph, int cStroke, int *piStrokeIndex);
  308. // Frees a word alt
  309. void FreeWordAlt (WORD_ALT *pAlt);
  310. // Frees a word alt list
  311. void FreeWordAltList (WORD_ALT_LIST *pAltList);
  312. // Frees a word map
  313. void FreeWordMap (WORD_MAP *pWordMap);
  314. // Frees a specific segmentation
  315. void FreeSegmentation (SEGMENTATION *pSeg);
  316. // frees the word maps in a segmentation
  317. void FreeSegmentationWordMaps (SEGMENTATION *pSeg);
  318. // Frees a segmentation set
  319. void FreeSegCol (SEG_COLLECTION *pSegCol);
  320. // Frees an ink line segmentation
  321. void FreeLineSegm (LINE_SEGMENTATION *pLineSegm);
  322. // compares the stroke contents of two word maps
  323. BOOL IsEqualWordMap (WORD_MAP *pMap1, WORD_MAP *pMap2);
  324. // compares the stroke contents of two word maps
  325. BOOL IsEqualOldWordMap (WORDMAP *pMap1, WORDMAP *pMap2);
  326. // compares two segmentations
  327. BOOL IsEqualSegmentation (SEGMENTATION *pSeg1, SEGMENTATION *pSeg2);
  328. // clones a wordmap, only copies the stroke part
  329. WORD_MAP *CloneWordMap (WORD_MAP *pOldWordMap);
  330. // finds a word_map in pool or wordmaps
  331. // returns the pointer to the word map if found
  332. // if the bAdd parameter is TRUE: adds the new word map if not found a return a pointer
  333. // other wise returns false
  334. WORD_MAP *FindWordMap (LINE_SEGMENTATION *pLineSegm, WORD_MAP *pWordMap, BOOL bAdd);
  335. // adds a new SegCol to a line segmentation
  336. SEG_COLLECTION *AddNewSegCol (LINE_SEGMENTATION *pLineSegm);
  337. // adds a new segmentation to a SegCol if it is a new one
  338. // returns TRUE: if the segmentation is added to the SegCol (new words are also added to
  339. // the word map pool in the line segmentation).
  340. // return FALSE: if no addition was made, TRUE otherwise
  341. BOOL AddNewSegmentation ( LINE_SEGMENTATION *pLineSegm,
  342. SEG_COLLECTION *pSegCol,
  343. SEGMENTATION *pNewSeg,
  344. BOOL bCheckForDuplicates
  345. );
  346. // adds a new word_map to a segmentation
  347. WORD_MAP *AddNewWordMap (SEGMENTATION *pSeg);
  348. // appends the wordmaps of one segmentation to another
  349. BOOL AppendSegmentation ( SEGMENTATION *pSrcSeg,
  350. int iStWrd,
  351. int iEndWrd,
  352. SEGMENTATION *pDestSeg
  353. );
  354. // adds a new stroke to a wordmap
  355. BOOL AddNewStroke (WORD_MAP *pWordMap, int iStrk);
  356. // reverses the order of words maps with a segmentation
  357. void ReverseSegmentationWords (SEGMENTATION *pSeg);
  358. // determines the min & max value for a strokeID in a wordmap
  359. int GetMinMaxStrokeID (WORD_MAP *pWord, int *piMin, int *piMax);
  360. BOOL InsertNewAlternate (WORD_ALT_LIST *pAltList, int iCost, unsigned char *pszWord);
  361. // This function finds the range on wordmaps in the search segmentation that
  362. // use exactly the same strokes in the specified wordmap map range in the matching
  363. // segmentation
  364. // The passed bEnd flag specified whether piEndWordMap has to be the last wordmap
  365. // of the search segmentation or not.
  366. // The return value will be FALSE if no wordmap range with the required specification
  367. // is found
  368. BOOL GetMatchingWordMapRange ( SEGMENTATION *pMatchSeg,
  369. int iStartWordMap,
  370. int iEndWordMap,
  371. SEGMENTATION *pSearchSeg,
  372. int *piStartWordMap,
  373. int *piEndWordMap,
  374. BOOL bBegin,
  375. BOOL bEnd
  376. );
  377. BOOL WordMapNew2Old (WORD_MAP *pNewWordMap, WORDMAP *pWordMap, BOOL bClone);
  378. BOOL AltListOld2New (ALTERNATES *pOldAltList, WORD_ALT_LIST *pAltList, BOOL bClone);
  379. BOOL AltListNew2Old ( HRC hrc,
  380. WORD_MAP *pNewWordMap,
  381. WORD_ALT_LIST *pAltList,
  382. ALTERNATES *pOldAltList,
  383. BOOL bClone
  384. );
  385. void FreeLines (LINEBRK *pLineBrk);
  386. BOOL AddNewStroke2Line (int cPt, POINT *pPt, FRAME *pFrame, INKLINE *pLine);
  387. int FindWordMapInXRCRESULT (XRCRESULT *pRes, WORDMAP *pMap);
  388. short AbsoluteToLatinLayout(int y, RECT *pRect);
  389. int LatinLayoutToAbsolute(short y, RECT *pRect);
  390. #ifdef __cplusplus
  391. };
  392. #endif
  393. #endif