(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; constsettings: 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,**分析如下:
proceduretwinfontglyphmanager.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的高手一起交流學習。由於我水平不好,而且是真實的從頭到尾的記錄,所以其中,特別是前面...