X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=inline;f=src%2Fflexui%2Ffui_gfx_gl.pas;h=bd409d38f9218b6579041ec92f52066b3c18ffd6;hb=35ca898ccf5f7fd5dce73e7ab5fa183a81cb7dc9;hp=f70e78967a753b4255e82716058fc49e04123a5d;hpb=6880f8a491a247a34d6afb5508d0a64196a3d26d;p=d2df-sdl.git diff --git a/src/flexui/fui_gfx_gl.pas b/src/flexui/fui_gfx_gl.pas index f70e789..bd409d3 100644 --- a/src/flexui/fui_gfx_gl.pas +++ b/src/flexui/fui_gfx_gl.pas @@ -15,6 +15,7 @@ * along with this program. If not, see . *) {$INCLUDE ../shared/a_modes.inc} +{$DEFINE FUI_TEXT_ICONS} unit fui_gfx_gl; interface @@ -149,6 +150,9 @@ var implementation +uses + utils; + // ////////////////////////////////////////////////////////////////////////// // // returns `false` if the color is transparent @@ -351,6 +355,10 @@ type procedure oglCreateTexture (); procedure oglDestroyTexture (); + procedure initDrawText (); + procedure doneDrawText (); + function drawCharInterim (x, y: Integer; const ch: AnsiChar): Integer; // return width (not including last empty pixel) + function drawCharInternal (x, y: Integer; const ch: AnsiChar): Integer; // return width (not including last empty pixel) function drawTextInternal (x, y: Integer; const s: AnsiString): Integer; // return width (not including last empty pixel) public @@ -408,7 +416,7 @@ end; procedure TGxBmpFont.oglCreateTexture (); begin - mTexId := createFontTexture(mFontBmp, mFontWdt, (mWidth <= 0)); + mTexId := createFontTexture(mFontBmp, mFontWdt, mHeight, (mWidth <= 0)); end; @@ -444,41 +452,65 @@ begin end; -// return width (not including last empty pixel) -function TGxBmpFont.drawTextInternal (x, y: Integer; const s: AnsiString): Integer; -var - ch: AnsiChar; - tx, ty: Integer; +procedure TGxBmpFont.initDrawText (); begin - if (Length(s) = 0) then begin result := 0; exit; end; - - result := -1; - glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_NOTEQUAL, 0.0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTexId); +end; - for ch in s do - begin - tx := (Integer(ch) mod 16)*8; - ty := (Integer(ch) div 16)*8; - glBegin(GL_QUADS); - glTexCoord2f((tx+0)/128.0, (ty+0)/128.0); glVertex2i(x+0, y+0); // top-left - glTexCoord2f((tx+8)/128.0, (ty+0)/128.0); glVertex2i(x+8, y+0); // top-right - glTexCoord2f((tx+8)/128.0, (ty+8)/128.0); glVertex2i(x+8, y+8); // bottom-right - glTexCoord2f((tx+0)/128.0, (ty+8)/128.0); glVertex2i(x+0, y+8); // bottom-left - glEnd(); - x += (mFontWdt[Byte(ch)] and $0f)+1; - result += (mFontWdt[Byte(ch)] and $0f)+1; - end; +procedure TGxBmpFont.doneDrawText (); +begin glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); end; +function TGxBmpFont.drawCharInterim (x, y: Integer; const ch: AnsiChar): Integer; +var + tx, ty: Integer; +begin + tx := (Integer(ch) mod 16)*8; + ty := (Integer(ch) div 16)*16; + glBegin(GL_QUADS); + glTexCoord2f((tx+0)/128.0, (ty+0)/256.0); glVertex2i(x+0, y+0); // top-left + glTexCoord2f((tx+8)/128.0, (ty+0)/256.0); glVertex2i(x+8, y+0); // top-right + glTexCoord2f((tx+8)/128.0, (ty+mHeight)/256.0); glVertex2i(x+8, y+mHeight); // bottom-right + glTexCoord2f((tx+0)/128.0, (ty+mHeight)/256.0); glVertex2i(x+0, y+mHeight); // bottom-left + glEnd(); + result := (mFontWdt[Byte(ch)] and $0f); +end; + + +function TGxBmpFont.drawCharInternal (x, y: Integer; const ch: AnsiChar): Integer; +begin + initDrawText(); + result := drawCharInterim(x, y, ch); + doneDrawText(); +end; + + +function TGxBmpFont.drawTextInternal (x, y: Integer; const s: AnsiString): Integer; +var + ch: AnsiChar; + wdt: Integer; +begin + if (Length(s) = 0) then begin result := 0; exit; end; + result := -1; + initDrawText(); + for ch in s do + begin + wdt := drawCharInterim(x, y, ch)+1; + x += wdt; + result += wdt; + end; + doneDrawText(); +end; + + // ////////////////////////////////////////////////////////////////////////// // var fontList: array of TGxBmpFont = nil; @@ -535,11 +567,17 @@ end; procedure createFonts (); begin deleteFonts(); - SetLength(fontList, 4); + SetLength(fontList, 10); fontList[0] := TGxBmpFont.Create('dos', 8, 8, @kgiFont8[0], @kgiFont8PropWidth[0]); fontList[1] := TGxBmpFont.Create('dos-prop', 0, 8, @kgiFont8[0], @kgiFont8PropWidth[0]); fontList[2] := TGxBmpFont.Create('msx', 6, 8, @kgiFont6[0], @kgiFont6PropWidth[0]); fontList[3] := TGxBmpFont.Create('msx-prop', 0, 8, @kgiFont6[0], @kgiFont6PropWidth[0]); + fontList[4] := TGxBmpFont.Create('win8', 8, 8, @kgiWFont8[0], @kgiWFont8Wdt[0]); + fontList[5] := TGxBmpFont.Create('win8-prop', 0, 8, @kgiWFont8[0], @kgiWFont8Wdt[0]); + fontList[6] := TGxBmpFont.Create('win14', 8, 14, @kgiFont14[0], @kgiFont14Wdt[0]); + fontList[7] := TGxBmpFont.Create('win14-prop', 0, 14, @kgiFont14[0], @kgiFont14Wdt[0]); + fontList[8] := TGxBmpFont.Create('win16', 8, 16, @kgiFont16[0], @kgiFont16Wdt[0]); + fontList[9] := TGxBmpFont.Create('win16-prop', 0, 16, @kgiFont16[0], @kgiFont16Wdt[0]); end; @@ -939,7 +977,7 @@ function TGxContext.drawChar (x, y: Integer; const ch: AnsiChar): Integer; // re begin result := mFont.charWidth(ch); if (not mActive) or (mClipRect.w < 1) or (mClipRect.h < 1) or (mColor.a = 0) then exit; - TGxBmpFont(mFont).drawTextInternal(x, y, ch); + TGxBmpFont(mFont).drawCharInternal(x, y, ch); end; function TGxContext.drawText (x, y: Integer; const s: AnsiString): Integer; // returns text width @@ -950,14 +988,57 @@ begin end; -function TGxContext.iconMarkWidth (ic: TMarkIcon): Integer; begin result := 11; end; -function TGxContext.iconMarkHeight (ic: TMarkIcon): Integer; begin result := 8; end; +function TGxContext.iconMarkWidth (ic: TMarkIcon): Integer; +begin + {$IFDEF FUI_TEXT_ICONS} + case ic of + TMarkIcon.Checkbox: result := textWidth('[x]'); + TMarkIcon.Radiobox: result := textWidth('(*)'); + else result := textWidth('[x]'); + end; + {$ELSE} + result := 11; + {$ENDIF} +end; + +function TGxContext.iconMarkHeight (ic: TMarkIcon): Integer; +begin + {$IFDEF FUI_TEXT_ICONS} + case ic of + TMarkIcon.Checkbox: result := textHeight('[x]'); + TMarkIcon.Radiobox: result := textHeight('(*)'); + else result := textHeight('[x]'); + end; + {$ELSE} + result := 8; + {$ENDIF} +end; procedure TGxContext.drawIconMark (ic: TMarkIcon; x, y: Integer; marked: Boolean); var + {$IFDEF FUI_TEXT_ICONS} + xstr: AnsiString; + {$ELSE} f: Integer; + {$ENDIF} begin if (not mActive) or (mClipRect.w < 1) or (mClipRect.h < 1) or (mColor.a = 0) then exit; + {$IFDEF FUI_TEXT_ICONS} + case ic of + TMarkIcon.Checkbox: xstr := '[x]'; + TMarkIcon.Radiobox: xstr := '(*)'; + else exit; + end; + if (marked) then + begin + drawText(x, y, xstr); + end + else + begin + drawChar(x, y, xstr[1]); + drawChar(x+textWidth(xstr)-charWidth(xstr[3]), y, xstr[3]); + end; + {$ELSE} if (ic = TMarkIcon.Checkbox) then begin vline(x, y, 7); @@ -995,23 +1076,61 @@ begin hline(x+4, y+5, 3); end; end; + {$ENDIF} end; -function TGxContext.iconWinWidth (ic: TWinIcon): Integer; begin result := 9; end; -function TGxContext.iconWinHeight (ic: TWinIcon): Integer; begin result := 8; end; +function TGxContext.iconWinWidth (ic: TWinIcon): Integer; +begin + {$IFDEF FUI_TEXT_ICONS} + case ic of + TWinIcon.Close: result := nmax(textWidth('[x]'), textWidth('[#]')); + else result := nmax(textWidth('[x]'), textWidth('[#]')); + end; + {$ELSE} + result := 9; + {$ENDIF} +end; + +function TGxContext.iconWinHeight (ic: TWinIcon): Integer; +begin + {$IFDEF FUI_TEXT_ICONS} + case ic of + TWinIcon.Close: result := nmax(textHeight('[x]'), textHeight('[#]')); + else result := nmax(textHeight('[x]'), textHeight('[#]')); + end; + {$ELSE} + result := 8; + {$ENDIF} +end; procedure TGxContext.drawIconWin (ic: TWinIcon; x, y: Integer; pressed: Boolean); var + {$IFDEF FUI_TEXT_ICONS} + xstr: AnsiString; + wdt: Integer; + {$ELSE} f: Integer; + {$ENDIF} begin if (not mActive) or (mClipRect.w < 1) or (mClipRect.h < 1) or (mColor.a = 0) then exit; + {$IFDEF FUI_TEXT_ICONS} + case ic of + TWinIcon.Close: if (pressed) then xstr := '[#]' else xstr := '[x]'; + else exit; + end; + wdt := nmax(textWidth('[x]'), textWidth('[#]')); + drawChar(x, y, xstr[1]); + drawChar(x+wdt-charWidth(xstr[3]), y, xstr[3]); + drawChar(x+((wdt-charWidth(xstr[2])) div 2), y, xstr[2]); + {$ELSE} if pressed then rect(x, y, 9, 8); for f := 1 to 5 do begin vline(x+1+f, y+f, 1); vline(x+1+6-f, y+f, 1); end; + {$ENDIF} end;