(5)UpdateCharRec
该函数的源码分析如下:
procedure TTextLayoutNG.UpdateCharRec(const ACanvas: TCanvas; NeedBitmap: Boolean; var NewRec: PCharRec; HasItem: Boolean; const CharDic: TCharDic; const AFont: TFont; const Ch: UCS4Char; const NeedPath: Boolean = False); var Map: TBitmapData; J: Integer; Bitmap: TBitmap; LFont: TFont; GlyphSettings: TFontGlyphSettings; begin { 新建一个记录,或释放原记录中的图形对象 } if not HasItem then New(NewRec) else begin FreeAndNil(NewRec.Glyph); FreeAndNil(NewRec.Bitmap); end; { 如果指定了字体则使用之,否则使用缺省字体 } if not Assigned(AFont) then LFont := Self.Font else LFont := AFont; { 使用Bitmap形式存储,或使用Path存储渲染过程 } GlyphSettings := []; if NeedBitmap then GlyphSettings := [TFontGlyphSetting.Bitmap, TFontGlyphSetting.PremultipliedAlpha]; if NeedPath then GlyphSettings := GlyphSettings + [TFontGlyphSetting.Path]; { 在TFontGlyphManager中使用当前的FontGlyph生成缺省图形 } NewRec.Glyph := TFontGlyphManager.Current.GetGlyph(Ch, LFont, FScale, GlyphSettings); { 计算基准线的位置 } CharDic.Baseline := TFontGlyphManager.Current.GetBaseline(LFont, FScale); { 如果采用图形模式,则生成之 } if not (TFontGlyphStyle.NoGlyph in NewRec.Glyph.Style) and Assigned(NewRec.Glyph.Bitmap) and (NewRec.Glyph.Bitmap.Width > 0) and (NewRec.Glyph.Bitmap.Height > 0) then begin { 采用图形渲染模式,生成Bitmap } if FRendering > 0 then begin Bitmap := TBitmap.Create(NewRec.Glyph.Bitmap.Width + AntiAliasMargin * 2, NewRec.Glyph.Bitmap.Height + AntiAliasMargin * 2); Bitmap.BitmapScale := FScale; { 将Glyph中的图形复制到Bitmap中 } if Bitmap.Map(TMapAccess.Write, Map) then try
FillChar(Map.Data^, Map.Pitch * Map.Height, 0); NewRec.Bitmap := Bitmap; NewRec.SrcRect := RectF(0, 0, NewRec.Glyph.Bitmap.Width, NewRec.Glyph.Bitmap.Height); NewRec.SrcRect.Offset(AntiAliasMargin, AntiAliasMargin); for J := 0 to NewRec.Glyph.Bitmap.Height - 1 do Move(NewRec.Glyph.Bitmap.Scanline[J]^, Map.GetPixelAddr(AntiAliasMargin, J + AntiAliasMargin)^, NewRec.Glyph.Bitmap.Pitch); finally Bitmap.Unmap(Map); end; { 构建图形列表,并将其放入 } if not Assigned(FNewGlyphList) then FNewGlyphList := TList<PCharRec>.Create; FNewGlyphList.Add(NewRec); end else { 直接将Glyph映射到Bitmap中 } MapGlyphToCache(NewRec); end else { 采用Path模式 } begin NewRec.Bitmap := nil; NewRec.SrcRect := RectF(0, 0, 0, 0); end; { 加入到列表中 } if not HasItem then CharDic.Add(Ch, NewRec); end;
其中2个重要的函数是:
TFontGlyphManager.Current.GetGlyph
TFontGlyphManager.Current.GetBaseline