private unsafe LsErr ExpandGlyphs( LsGlyphRunInfo *plsglyphrunInfo, int interWordExpandTo, int **pplsExpansionLeft, int **pplsExpansionRight, LsExpType *plsexptype, LsExpType interWordExpansionType, LsExpType interLetterExpansionType ) { char* pwch = plsglyphrunInfo->pwch; ushort* pgmap = plsglyphrunInfo->rggmap; int cchRun = plsglyphrunInfo->cwch; int cgiRun = plsglyphrunInfo->cgindex; int ich = 0; int igi = pgmap[ich]; int cgi = 0; while (ich < cchRun) { int cch = 1; while (ich + cch < cchRun && pgmap[ich + cch] == igi) cch++; cgi = (ich + cch == cchRun) ? cgiRun - igi : pgmap[ich + cch] - igi; int i, j; for (j = 0; j < cch; j++) { ushort flags = (ushort)(Classification.CharAttributeOf((int)Classification.GetUnicodeClassUTF16(pwch[ich + j]))).Flags; if ((flags & ((ushort)CharacterAttributeFlags.CharacterSpace)) != 0) break; } int glyphAdvance = 0; for (i = 0; i < cgi; i++) { glyphAdvance += plsglyphrunInfo->rgduWidth[igi + i]; pplsExpansionLeft[0][igi + i] = 0; pplsExpansionLeft[1][igi + i] = 0; pplsExpansionLeft[2][igi + i] = 0; pplsExpansionRight[0][igi + i] = 0; pplsExpansionRight[1][igi + i] = 0; pplsExpansionRight[2][igi + i] = 0; if (i == cgi - 1) { if (cch == 1 && j < cch) { int expandedBy = Math.Max(0, interWordExpandTo - glyphAdvance); pplsExpansionRight[0][igi + i] = expandedBy; pplsExpansionRight[1][igi + i] = expandedBy * Constants.AcceptableLineStretchability; pplsExpansionRight[2][igi + i] = FullText.FormatWidth; plsexptype[igi + i] = interWordExpansionType; } else { pplsExpansionRight[2][igi + i] = FullText.FormatWidth; plsexptype[igi + i] = interLetterExpansionType; } } } ich += cch; igi += cgi; } Invariant.Assert(igi == cgiRun); return LsErr.None; }
private unsafe LsErr CompressGlyphs( LsGlyphRunInfo *plsglyphrunInfo, int interWordCompressTo, int **pplsCompressionLeft, int **pplsCompressionRight ) { char* pwch = plsglyphrunInfo->pwch; ushort* pgmap = plsglyphrunInfo->rggmap; int cchRun = plsglyphrunInfo->cwch; int cgiRun = plsglyphrunInfo->cgindex; int ich = 0; int igi = pgmap[ich]; int cgi = 0; while (ich < cchRun) { int cch = 1; while (ich + cch < cchRun && pgmap[ich + cch] == igi) cch++; cgi = (ich + cch == cchRun) ? cgiRun - igi : pgmap[ich + cch] - igi; int i, j; for (j = 0; j < cch; j++) { ushort flags = (ushort)(Classification.CharAttributeOf((int)Classification.GetUnicodeClassUTF16(pwch[ich + j]))).Flags; if ((flags & ((ushort)CharacterAttributeFlags.CharacterSpace)) != 0) break; } int glyphAdvance = 0; for (i = 0; i < cgi; i++) { glyphAdvance += plsglyphrunInfo->rgduWidth[igi + i]; pplsCompressionLeft[0][igi + i] = 0; pplsCompressionLeft[1][igi + i] = 0; pplsCompressionLeft[2][igi + i] = 0; pplsCompressionRight[0][igi + i] = 0; pplsCompressionRight[1][igi + i] = 0; pplsCompressionRight[2][igi + i] = 0; if ( i == cgi - 1 && cch == 1 && j < cch ) { pplsCompressionRight[0][igi + i] = Math.Max(0, glyphAdvance - interWordCompressTo); } } ich += cch; igi += cgi; } Invariant.Assert(igi == cgiRun); return LsErr.None; }
internal unsafe LsErr GetGlyphExpansionInfoFullMixed( IntPtr pols, // Line Layout context LsDevice device, // kind of device LsTFlow textFlow, // text flow LsGlyphRunInfo *plsglyphrunInfo, // glyph-based run info LsNeighborInfo *plsneighborInfoLeft, // left neighbor info LsNeighborInfo *plsneighborInfoRight, // right neigbor info int maxPriorityLevel, // maximum priority level int **pplsexpansionLeft, // [in/out] fill in left expansion amount per priority level on the way out int **pplsexpansionRight, // [in/out] fill in right expansion amount per priority level on the way out LsExpType *plsexptype, // [in/out] fill in glyph expansion type for each glyph int *pduMinInk // [in/out] fill in glyph minimum expansion for exptAddInkContinuous ) { LsErr lserr = LsErr.None; Plsrun plsrun = Plsrun.Undefined; LSRun lsrun = null; try { Invariant.Assert(maxPriorityLevel == 3); plsrun = plsglyphrunInfo->plsrun; lsrun = FullText.StoreFrom(plsrun).GetRun(plsrun); int em = lsrun.EmSize; return ExpandGlyphs( plsglyphrunInfo, (int)(em * Constants.MaxInterWordExpansionPerEm), pplsexpansionLeft, pplsexpansionRight, plsexptype, LsExpType.AddWhiteSpace, // inter-word expansion type ((lsrun.BidiLevel & 1) == 0 ? LsExpType.AddWhiteSpace : LsExpType.None) ); } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("GetGlyphExpansionInfoFullMixed", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal unsafe LsErr GetGlyphCompressionInfoFullMixed( IntPtr pols, // Line Layout context LsDevice device, // kind of device LsTFlow textFlow, // text flow LsGlyphRunInfo *plsglyphrunInfo, // glyph-based run info LsNeighborInfo *plsneighborInfoLeft, // left neighbor info LsNeighborInfo *plsneighborInfoRight, // right neigbor info int maxPriorityLevel, // maximum priority level int **pplscompressionLeft, // [in/out] fill in left compression amount per priority level on the way out int **pplscompressionRight // [in/out] fill in right compression amount per priority level on the way out ) { LsErr lserr = LsErr.None; Plsrun plsrun = Plsrun.Undefined; LSRun lsrun = null; try { Invariant.Assert(maxPriorityLevel == 3); plsrun = plsglyphrunInfo->plsrun; lsrun = FullText.StoreFrom(plsrun).GetRun(plsrun); int em = lsrun.EmSize; return CompressGlyphs( plsglyphrunInfo, (int)(em * Constants.MinInterWordCompressionPerEm), pplscompressionLeft, pplscompressionRight ); } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("GetGlyphCompressionInfoFullMixed", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }