Using WPF Font Geometry
Getting WPF Font Geometry
public static Geometry BuildGeometry(string lsFntFamily, string lsCH, double positionXDiu, double positionYDiu)
{
System.Windows.Media.Geometry lGeom = null;
try
{
System.Windows.Media.FormattedText lFTXT = new System.Windows.Media.FormattedText(lsCH,
System.Threading.Thread.CurrentThread.CurrentUICulture,
FlowDirection.LeftToRight,
new Typeface(lsFntFamily),
UCNV.GetDIUFromPoint(_DEFFONTSIZE),
System.Windows.Media.Brushes.Black);
lGeom = lFTXT.BuildGeometry(new Point(positionXDiu, positionYDiu));
}
catch (Exception lExe)
{
lGeom = null;
ORIONDEBUG.LOG(LogInfo.EnumLogLevel.ERROR, "WpfFontCache::BuildGeometry()", lExe);
}
return lGeom;
}
Drawing WPF Font Geometry
- Set rotation
Matrix lMtrx = new Matrix();
if (lCD.fRotation != 0F)
{
Point lptRotateCenterPercent = WPF.UC_Item.GetRotateCenterPercent(lCD);
lMtrx.RotateAt(lCD.fRotation, lSzTBoxDIU.Width * lptRotateCenterPercent.X, lSzTBoxDIU.Height * lptRotateCenterPercent.Y);
}
lCD.cItemCanvas.RenderTransform = new MatrixTransform(lMtrx); - Get geometry from cache
System.Windows.Media.Geometry lGeom = GlyphInfoCache.GetWpfGeomCache(lGlyph, lPD.fWidthDPI, lPD.fHeightDPI, ldFontSize, ldFontScaleW, 1F);
- Set Italic, Horizontal/Vertical Flips
lMtrx = ((MatrixTransform)lGeom.Transform).Matrix;
if (lCD.cbFontFlipVert)
lMtrx.Append(new Matrix(1, 0, 0, -1, 0, UCNV.GetDIUFromPixel(lSZFCH.CharHeight, lPD.fHeightDPI)));
if (lCD.cbFontFlipHorz)
lMtrx.Append(new Matrix(-1, 0, 0, 1, UCNV.GetDIUFromPixel(lSZFCH.GapHorz, lPD.fWidthDPI), 0));
if (lCD.bFontStyleItalic)
{
double ldItalicization = -0.35;// -lfFontSizePX / UCNV.GetPixelFromPoint(50F, lPD.fWidthDPI);
lMtrx.Append(new Matrix(1, 0, ldItalicization, 1, UCNV.GetDIUFromPixel(lSZFCH.CharHeight, lPD.fWidthDPI) * 0.35, 0));
}
lGeom.Transform = new MatrixTransform(lMtrx); - Set font size
- WPF Font is extracted 10-point of size, and scale it to actual size when used
double ldFontSizeScale = ldFontSizePT / GlyphInfoCache._DEFFONTSIZE;
ldFontScaleW *= ldFontSizeScale;
ldFontScaleH *= ldFontSizeScale;
lGeom = lGlyph.cGeom.Clone();
System.Windows.Media.Matrix lMtrx = new System.Windows.Media.Matrix();
lMtrx.Scale(ldFontScaleW, ldFontScaleH);
lGeom.Transform = new MatrixTransform(lMtrx);
- WPF Font is extracted 10-point of size, and scale it to actual size when used
...
Matrix lMtrx = new Matrix();
if (lCD.fRotation != 0F)
{
Point lptRotateCenterPercent = WPF.UC_Item.GetRotateCenterPercent(lCD);
lMtrx.RotateAt(lCD.fRotation, lSzTBoxDIU.Width * lptRotateCenterPercent.X, lSzTBoxDIU.Height * lptRotateCenterPercent.Y);
}
lCD.cItemCanvas.RenderTransform = new MatrixTransform(lMtrx);
double ldWpfStringPosAdjustX = 0; //WpfFontInfo._DEFFONTSIZE / 5;
double ldWpfStringPosAdjustY = 0; // WpfFontInfo._DEFFONTSIZE / 10;
foreach (OrionTextBoxInfo.LineChars lLine in llLNChars)
{
if (lLine.LSZFCH == null || lLine.LSZFCH.Count <= 0)
continue;
Point lPtRPos = new Point(UCNV.GetDIUFromPixel(lLine.PTF.X, lPD.fWidthDPI) + ldWpfStringPosAdjustX,
UCNV.GetDIUFromPixel(lLine.PTF.Y, lPD.fHeightDPI) - ldWpfStringPosAdjustY);
double ldInitPosX = lPtRPos.X;
double ldInitPosY = lPtRPos.Y;
double ldLineWidth = 0;
//
List<OrionConfigInfo.OrionColor> llColors = new List<OrionConfigInfo.OrionColor>();
int liColorIX = 0;
if (lCD.cColorList.cbUseColorList)
llColors = lCD.cColorList.GetColors(lLine.LSZFCH.Count);
//
foreach (OrionTextBoxInfo.SizeFChar lSZFCH in lLine.LSZFCH)
{
if (lCD.cColorList.cbUseColorList)
{
lForeColor = new NewColor(llColors[liColorIX]);
liColorIX++;
}
GlyphInfoCache lGlyph = lSZFCH.cGlyph;
if (lGlyph == null || lGlyph.cGeom == null)
throw new Exception("OrinWpfDesigner::DrawData_WPF() GlyphInfoCache:lGlyph is NULL");
System.Windows.Media.Geometry lGeom = GlyphInfoCache.GetWpfGeomCache(lGlyph, lPD.fWidthDPI, lPD.fHeightDPI, ldFontSize, ldFontScaleW, 1F);
if (lGeom == null)
throw new Exception("OrinWpfDesigner::DrawData_WPF() GlyphInfoCache.GetWpfGeomCache() Return value is NULL");
if (lCD.bFontStyleItalic || lCD.cbFontFlipVert || lCD.cbFontFlipHorz)
{
lMtrx = ((MatrixTransform)lGeom.Transform).Matrix;
if (lCD.cbFontFlipVert)
lMtrx.Append(new Matrix(1, 0, 0, -1, 0, UCNV.GetDIUFromPixel(lSZFCH.CharHeight, lPD.fHeightDPI)));
if (lCD.cbFontFlipHorz)
lMtrx.Append(new Matrix(-1, 0, 0, 1, UCNV.GetDIUFromPixel(lSZFCH.GapHorz, lPD.fWidthDPI), 0));
if (lCD.bFontStyleItalic)
{
double ldItalicization = -0.35;// -lfFontSizePX / UCNV.GetPixelFromPoint(50F, lPD.fWidthDPI);
lMtrx.Append(new Matrix(1, 0, ldItalicization, 1, UCNV.GetDIUFromPixel(lSZFCH.CharHeight, lPD.fWidthDPI) * 0.35, 0));
}
lGeom.Transform = new MatrixTransform(lMtrx);
}
GlyphInfoCache.DrawPathData_WPF(lCD.cItemCanvas, lPD, lCD, lSZFCH, ldFontSize, lForeColor, lGeom, lPtRPos);
ldLineWidth += UCNV.GetDIUFromPixel(lSZFCH.GapHorz, lPD.fWidthDPI);
lPtRPos.X += UCNV.GetDIUFromPixel(lSZFCH.GapHorz, lPD.fWidthDPI);
}
if (lCD.bFontStyleStrikeout || lCD.bFontStyleUnderline)
{
this.DrawSThru_ULine_WPF(lCD.cItemCanvas, lCD, lPD, lLine, ldInitPosX, ldInitPosY, ldLineWidth);
}
}
... GlyphInfoCache.cs
public static bool DrawPathData_WPF(Canvas lCNVS, OD_PageData lPD, OD_ColumnData lCD,
OrionTextBoxInfo.SizeFChar lSZFCH, double ldFontSizePT, NewColor lncrFore,
System.Windows.Media.Geometry lGeom, System.Windows.Point lptPos)
{
bool lbSuccess = false;
try
{
//
if (lSZFCH.cGlyph != null && lSZFCH.cGlyph.isSubstituted && lPD.fontSubstitutionPositionAdjust)
{
double fontScale = ldFontSizePT / GlyphInfoCache._DEFFONTSIZE;
double adjustSubstitutedFontPositionY = UCNV.GetDIUFromPoint(lSZFCH.cGlyph.baselineDifference) * fontScale * 0.7;
lptPos.Y += adjustSubstitutedFontPositionY;
}
//
System.Windows.Shapes.Path lFntPath = new System.Windows.Shapes.Path();
lFntPath.Data = lGeom;
lFntPath.Margin = new Thickness(lptPos.X, lptPos.Y, 0, 0);
if (lCD.cbFontOutline)
{
lFntPath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromRgb(lncrFore.RGB.R, lncrFore.RGB.G, lncrFore.RGB.B));
lFntPath.StrokeThickness = UCNV.GetDIUFromMM(lCD.cfPenWidth);
if (lFntPath.StrokeThickness < 0.2)
lFntPath.StrokeThickness = 0.2;
lFntPath.StrokeDashArray = OrionWpfDesigner.SetLineDash(lCD.cPenDashStyle);
lCNVS.Children.Add(lFntPath);
}
else
{
lFntPath.Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(lncrFore.RGB.R, lncrFore.RGB.G, lncrFore.RGB.B));
if (lCD.bFontStyleBold)
{
lFntPath.Stroke = new SolidColorBrush(System.Windows.Media.Color.FromRgb(lncrFore.RGB.R, lncrFore.RGB.G, lncrFore.RGB.B));
lFntPath.StrokeThickness = UCNV.GetDIUFromPoint(ldFontSizePT / 100.0 * 4.0);
if (lFntPath.StrokeThickness < 0.2)
lFntPath.StrokeThickness = 0.2;
}
lCNVS.Children.Add(lFntPath);
}
lbSuccess = true;
}
catch (Exception lExe)
{
lbSuccess = false;
ORIONDEBUG.LOG(LogInfo.EnumLogLevel.ERROR, "GlyphInfoCache::DrawPathData_WPF()", lExe);
}
finally
{
}
return lbSuccess;
}
...