FireMonkey 原始碼學習(6)

2021-09-06 16:16:43 字數 4759 閱讀 8185

(6)getglyph和getbaseline

tfontglyphmanager是乙個抽象類,在不同平台上的實現是不同的,以windows為例,在fmx.fontglyphs.win.pas檔案中定義了:

twinfontglyphmanager = class

(tfontglyphmanager)

...protected

function dogetglyph(const char: ucs4char; const settings: tfontglyphsettings): tfontglyph; override

;

function dogetbaseline: single; override

; ...

dogetglyph的實現**如下:

function twinfontglyphmanager.dogetglyph(const char: ucs4char; const

settings: tfontglyphsettings): tfontglyph;

varcharsstring:

string

; abc: tabcfloat;

charsize: tsize;

glyphrect: trect;

i, j: integer;

c: byte;

color: talphacolorrec;

glyphstyle: tfontglyphstyles;

bitmap: twinbitmap;

begin

charsstring :=system.char.convertfromutf32(char);

gettextextentpoint32w(fmeasurebitmap.dc, charsstring,

1, charsize);

getcharabcwidthsfloat(fmeasurebitmap.dc, char, char, abc);

if tfontglyphsetting.bitmap in settings then

begin

bitmap := createbitmap(max(ceil(abs(abc.abcfa) + abs(abc.abcfb) +abs(abc.abcfc)), charsize.cx), charsize.cy);

filllongword(bitmap.bits, bitmap.width *bitmap.height, talphacolorrec.white);

settextcolor(bitmap.dc, rgb(

0, 0, 0

)); setbkcolor(bitmap.dc, rgb(

255, 255, 255

));

settextalign(bitmap.dc, ta_top);

selectobject(bitmap.dc, ffont);

textout(bitmap.dc, -trunc(abc.abcfa), 0, @char, 1

);

glyphrect := trect.create(bitmap.width, charsize.cy, 0, 0

);

for i := 0

to bitmap.width - 1

dofor j := 0

to charsize.cy - 1

dobegin

c := bitmap.bits[j * bitmap.width +i].r;

if c > 0

then

begin

if j < glyphrect.top then

glyphrect.top :=j;

if i < glyphrect.left then

glyphrect.left :=i;

end;

end;

for i := bitmap.width - 1

downto glyphrect.left do

for j := charsize.cy - 1

downto glyphrect.top do

begin

c := bitmap.bits[j * bitmap.width +i].r;

if c > 0

then

begin

if j > glyphrect.bottom then

glyphrect.bottom :=j;

if i > glyphrect.right then

glyphrect.right :=i;

end;

end;

glyphrect.left :=min(charsize.cx, glyphrect.left);

glyphrect.top :=min(charsize.cy, glyphrect.top);

glyphrect.right := max(charsize.cx, glyphrect.right + 1

); glyphrect.bottom := max(charsize.cy, glyphrect.bottom + 1

);

end;

glyphstyle :=;

ifnot hasglyph(char) then

glyphstyle :=[tfontglyphstyle.noglyph];

result := tfontglyph.create(tpoint.create(glyphrect.left +trunc(abc.abcfa), glyphrect.top),

abc.abcfa + abc.abcfb +abc.abcfc, charsize.height, glyphstyle);

if tfontglyphsetting.bitmap in settings then

begin

result.bitmap.setsize(max(glyphrect.width, glyphrect.right), glyphrect.height, tpixelformat.bgra);

for i := glyphrect.left to glyphrect.right - 1

dofor j := glyphrect.top to glyphrect.bottom - 1

dobegin

color := bitmap.bits[j * bitmap.width +i];

if color.r < 255

then

begin

c := 255 - ((integer(color.r * 54) + integer(color.g * 183) + integer(color.b * 19)) div

256);

if tfontglyphsetting.premultipliedalpha in settings then

result.bitmap.pixels[i - glyphrect.left, j - glyphrect.top] :=makecolor(c, c, c, c)

else

result.bitmap.pixels[i - glyphrect.left, j - glyphrect.top] :=makecolor($ff, $ff, $ff, c);

end;

end;

destroybitmap(bitmap);

end;end;

dogetbaseline的實現**直接返回了fbaseline的值,fbaseline是在載入資源時生成,其核心函式為loadresource,**分析如下:

procedure

twinfontglyphmanager.loadresource;

varheight: integer;

dwbold, dwitalic: cardinal;

metrics: ttextmetric;

begin

height := -round(currentsettings.size *currentsettings.scale);

if tfontstyle.fsbold in currentsettings.style then

dwbold :=fw_bold

else

dwbold :=fw_normal;

if tfontstyle.fsitalic in currentsettings.style then

dwitalic := 1

else

dwitalic := 0;

ffont := createfont(height, 0, 0, 0

, dwbold, dwitalic,

0, 0

, default_charset, out_default_precis,

clip_default_precis, default_quality,

default_pitch

orff_dontcare, pchar(currentsettings.family));

if ffont = 0

then

exit;

selectobject(fmeasurebitmap.dc, ffont);

gettextmetrics(fmeasurebitmap.dc, metrics);

fbaseline :=metrics.tmascent;

end;

原始碼學習 ArrayList的擴容原始碼分析

原始碼如下 下面是arraylist的擴容機制 arraylist的擴容機制提高了效能,如果每次只擴充乙個,那麼頻繁的插入會導致頻繁的拷貝,降低效能,而arraylist的擴容機制避免了這種情況。如有必要,增加此arraylist例項的容量,以確保它至少能容納元素的數量 param mincapac...

PicoContainer原始碼學習

介紹下自己,我叫stef wu,是個菜鳥,現在在easyjf團隊學習,得到了大峽等人的熱情幫助。本序列文章是以前在學習研究picocontainer時所記錄下來的,希望借本文,能和正在學習pico新手或者研究pico的高手一起交流學習。由於我水平不好,而且是真實的從頭到尾的記錄,所以其中,特別是前面...

PicoContainer原始碼學習

介紹下自己,我叫stef wu,是個菜鳥,現在在easyjf團隊學習,得到了大峽等人的熱情幫助。本序列文章是以前在學習研究picocontainer時所記錄下來的,希望借本文,能和正在學習pico新手或者研究pico的高手一起交流學習。由於我水平不好,而且是真實的從頭到尾的記錄,所以其中,特別是前面...