Browse Source

* implemented post processing

* added Format Lumiance8
master
Bergmann89 11 years ago
parent
commit
ee6d1b615f
8 changed files with 839 additions and 356 deletions
  1. +6
    -1
      examples/simple/TextSuiteTest.lpi
  2. +1
    -1
      examples/simple/TextSuiteTest.lpr
  3. +245
    -205
      examples/simple/TextSuiteTest.lps
  4. +28
    -7
      examples/simple/uMainForm.pas
  5. +261
    -0
      utsPostProcess.pas
  6. +4
    -0
      utsRendererOpenGL.pas
  7. +211
    -136
      utsTextSuite.pas
  8. +83
    -6
      utsTypes.pas

+ 6
- 1
examples/simple/TextSuiteTest.lpi View File

@@ -33,7 +33,7 @@
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="9">
<Units Count="10">
<Unit0>
<Filename Value="TextSuiteTest.lpr"/>
<IsPartOfProject Value="True"/>
@@ -80,6 +80,11 @@
<IsPartOfProject Value="True"/>
<UnitName Value="utsCodePages"/>
</Unit8>
<Unit9>
<Filename Value="..\..\utsPostProcess.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsPostProcess"/>
</Unit9>
</Units>
</ProjectOptions>
<CompilerOptions>


+ 1
- 1
examples/simple/TextSuiteTest.lpr View File

@@ -7,7 +7,7 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, sysutils, Forms, uMainForm,
utsFontCreatorGDI, utsUtils, utsTypes, utsTtfUtils, utsTextSuite, utsRendererOpenGL, utsCodePages;
utsFontCreatorGDI, utsUtils, utsTypes, utsTtfUtils, utsTextSuite, utsRendererOpenGL, utsCodePages, utsPostProcess;

{$R *.res}



+ 245
- 205
examples/simple/TextSuiteTest.lps View File

@@ -4,13 +4,13 @@
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="53">
<Units Count="60">
<Unit0>
<Filename Value="TextSuiteTest.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="29" Y="20"/>
<UsageCount Value="97"/>
<UsageCount Value="106"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
@@ -20,20 +20,19 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMainForm"/>
<IsVisibleTab Value="True"/>
<TopLine Value="122"/>
<CursorPos X="39" Y="146"/>
<UsageCount Value="97"/>
<TopLine Value="73"/>
<CursorPos X="78" Y="89"/>
<UsageCount Value="106"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsRendererOpenGL"/>
<EditorIndex Value="6"/>
<TopLine Value="233"/>
<CursorPos X="43" Y="277"/>
<UsageCount Value="25"/>
<EditorIndex Value="7"/>
<TopLine Value="37"/>
<CursorPos X="35" Y="114"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
@@ -41,65 +40,75 @@
<IsPartOfProject Value="True"/>
<UnitName Value="utsTextSuite"/>
<EditorIndex Value="1"/>
<TopLine Value="2113"/>
<CursorPos X="27" Y="2129"/>
<UsageCount Value="25"/>
<TopLine Value="10"/>
<CursorPos X="5" Y="26"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
<Filename Value="..\..\utsTtfUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<UsageCount Value="25"/>
<UsageCount Value="34"/>
</Unit4>
<Unit5>
<Filename Value="..\..\utsTypes.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsTypes"/>
<EditorIndex Value="4"/>
<TopLine Value="155"/>
<CursorPos X="10" Y="171"/>
<UsageCount Value="25"/>
<EditorIndex Value="5"/>
<TopLine Value="282"/>
<CursorPos Y="298"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\..\utsUtils.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsUtils"/>
<EditorIndex Value="2"/>
<EditorIndex Value="3"/>
<TopLine Value="161"/>
<CursorPos X="23" Y="180"/>
<UsageCount Value="25"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\..\utsFontCreatorGDI.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsFontCreatorGDI"/>
<EditorIndex Value="5"/>
<EditorIndex Value="6"/>
<TopLine Value="643"/>
<CursorPos X="40" Y="628"/>
<UsageCount Value="25"/>
<CursorPos X="33" Y="659"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit7>
<Unit8>
<Filename Value="..\..\utsCodePages.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsCodePages"/>
<EditorIndex Value="3"/>
<EditorIndex Value="4"/>
<TopLine Value="196"/>
<CursorPos X="30" Y="8"/>
<UsageCount Value="22"/>
<UsageCount Value="31"/>
<Loaded Value="True"/>
</Unit8>
<Unit9>
<Filename Value="..\..\utsPostProcess.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsPostProcess"/>
<EditorIndex Value="2"/>
<TopLine Value="229"/>
<CursorPos X="13" Y="250"/>
<UsageCount Value="29"/>
<Loaded Value="True"/>
</Unit9>
<Unit10>
<Filename Value="new\utsTextSuite.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="1886"/>
<CursorPos X="33" Y="1904"/>
<UsageCount Value="91"/>
</Unit9>
<Unit10>
</Unit10>
<Unit11>
<Filename Value="old\TextSuite.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
@@ -112,240 +121,240 @@
<CursorPos X="3" Y="302"/>
</ExtraEditor1>
<UsageCount Value="86"/>
</Unit10>
<Unit11>
</Unit11>
<Unit12>
<Filename Value="old\TextSuiteImports.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="656"/>
<CursorPos X="20" Y="635"/>
<UsageCount Value="86"/>
</Unit11>
<Unit12>
</Unit12>
<Unit13>
<Filename Value="old\TextSuiteWideUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="1243"/>
<CursorPos X="18" Y="1257"/>
<UsageCount Value="86"/>
</Unit12>
<Unit13>
</Unit13>
<Unit14>
<Filename Value="old\TextSuiteClasses.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="654"/>
<CursorPos X="25" Y="673"/>
<UsageCount Value="86"/>
</Unit13>
<Unit14>
</Unit14>
<Unit15>
<Filename Value="old\TextSuitePostProcess.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="163"/>
<CursorPos X="61" Y="141"/>
<UsageCount Value="86"/>
</Unit14>
<Unit15>
</Unit15>
<Unit16>
<Filename Value="old\TextSuiteTTFUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="83"/>
<CursorPos X="3" Y="91"/>
<UsageCount Value="86"/>
</Unit15>
<Unit16>
</Unit16>
<Unit17>
<Filename Value="old\TextSuiteVersion.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="86"/>
</Unit16>
<Unit17>
</Unit17>
<Unit18>
<Filename Value="new\utsFontCreatorGDI.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="655"/>
<CursorPos X="53" Y="662"/>
<UsageCount Value="50"/>
</Unit17>
<Unit18>
</Unit18>
<Unit19>
<Filename Value="new\utsTtfUtils.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="128"/>
<CursorPos X="17" Y="144"/>
<UsageCount Value="42"/>
</Unit18>
<Unit19>
</Unit19>
<Unit20>
<Filename Value="new\utsTypes.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="152"/>
<CursorPos X="5" Y="168"/>
<UsageCount Value="42"/>
</Unit19>
<Unit20>
</Unit20>
<Unit21>
<Filename Value="new\utsUtils.pas"/>
<EditorIndex Value="-1"/>
<CursorPos Y="20"/>
<UsageCount Value="42"/>
</Unit20>
<Unit21>
</Unit21>
<Unit22>
<Filename Value="new\utsRendererOpenGL.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="356"/>
<CursorPos X="20" Y="376"/>
<UsageCount Value="39"/>
</Unit21>
<Unit22>
</Unit22>
<Unit23>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcTypes.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="261"/>
<CursorPos X="3" Y="277"/>
<UsageCount Value="37"/>
</Unit22>
<Unit23>
</Unit23>
<Unit24>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\dglOpenGL.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="1066"/>
<CursorPos X="27" Y="1082"/>
<UsageCount Value="32"/>
</Unit23>
<Unit24>
</Unit24>
<Unit25>
<Filename Value="new\uglctextsuite.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="13"/>
</Unit24>
<Unit25>
</Unit25>
<Unit26>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\ustringh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="110"/>
<CursorPos X="10" Y="126"/>
<UsageCount Value="27"/>
</Unit25>
<Unit26>
</Unit26>
<Unit27>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\ustrings.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="1819"/>
<CursorPos X="37" Y="2066"/>
<UsageCount Value="4"/>
</Unit26>
<Unit27>
</Unit27>
<Unit28>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\systemh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="756"/>
<CursorPos X="32" Y="774"/>
<UsageCount Value="25"/>
</Unit27>
<Unit28>
</Unit28>
<Unit29>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\heaph.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="71"/>
<CursorPos X="10" Y="95"/>
<UsageCount Value="26"/>
</Unit28>
<Unit29>
</Unit29>
<Unit30>
<Filename Value="old\TextSuiteCPUUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<CursorPos X="23" Y="20"/>
<UsageCount Value="16"/>
</Unit29>
<Unit30>
</Unit30>
<Unit31>
<Filename Value="..\glBitmap\glBitmap\glBitmap.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="14" Y="14"/>
<UsageCount Value="4"/>
</Unit30>
<Unit31>
</Unit31>
<Unit32>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\math.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="1011"/>
<CursorPos X="47" Y="1015"/>
<UsageCount Value="8"/>
</Unit31>
<Unit32>
</Unit32>
<Unit33>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\mathh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="84"/>
<CursorPos X="14" Y="101"/>
<UsageCount Value="8"/>
</Unit32>
<Unit33>
</Unit33>
<Unit34>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\genmath.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="152"/>
<CursorPos X="10" Y="155"/>
<UsageCount Value="8"/>
</Unit33>
<Unit34>
</Unit34>
<Unit35>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\dynlibs.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="41"/>
<CursorPos X="10" Y="58"/>
<UsageCount Value="13"/>
</Unit34>
<Unit35>
</Unit35>
<Unit36>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\win\dynlibs.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="9"/>
<CursorPos X="3" Y="26"/>
<UsageCount Value="13"/>
</Unit35>
<Unit36>
</Unit36>
<Unit37>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\win\sysosh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="11"/>
<CursorPos X="3" Y="19"/>
<UsageCount Value="13"/>
</Unit36>
<Unit37>
</Unit37>
<Unit38>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\objpash.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="177"/>
<CursorPos X="22" Y="195"/>
<UsageCount Value="17"/>
</Unit37>
<Unit38>
</Unit38>
<Unit39>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\sysutils\sysunih.inc"/>
<EditorIndex Value="6"/>
<EditorIndex Value="12"/>
<WindowIndex Value="1"/>
<TopLine Value="25"/>
<CursorPos X="34" Y="43"/>
<UsageCount Value="23"/>
<UsageCount Value="28"/>
<Loaded Value="True"/>
</Unit38>
<Unit39>
</Unit39>
<Unit40>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\packages\fcl-base\src\syncobjs.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="113"/>
<CursorPos X="25" Y="115"/>
<UsageCount Value="18"/>
</Unit39>
<Unit40>
</Unit40>
<Unit41>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\classes\classesh.inc"/>
<WindowIndex Value="1"/>
<TopLine Value="311"/>
<CursorPos X="14" Y="327"/>
<UsageCount Value="20"/>
<UsageCount Value="25"/>
<Loaded Value="True"/>
</Unit40>
<Unit41>
</Unit41>
<Unit42>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\objpas.inc"/>
<EditorIndex Value="5"/>
<EditorIndex Value="11"/>
<WindowIndex Value="1"/>
<CursorPos X="35" Y="24"/>
<UsageCount Value="17"/>
<UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit41>
<Unit42>
</Unit42>
<Unit43>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\control.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2843"/>
<CursorPos Y="2858"/>
<UsageCount Value="15"/>
</Unit42>
<Unit43>
</Unit43>
<Unit44>
<Filename Value="C:\Users\Erik\Desktop\RectPacking\unit1.pas"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
@@ -355,223 +364,254 @@
<WindowIndex Value="1"/>
<TopLine Value="376"/>
<CursorPos X="74" Y="397"/>
<UsageCount Value="18"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
</Unit43>
<Unit44>
</Unit44>
<Unit45>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcArrayBuffer.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="102"/>
<CursorPos X="37" Y="112"/>
<UsageCount Value="12"/>
</Unit44>
<Unit45>
</Unit45>
<Unit46>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcBitmap.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="1047"/>
<CursorPos X="15" Y="1043"/>
<UsageCount Value="10"/>
</Unit45>
<Unit46>
</Unit46>
<Unit47>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\objpas.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="19"/>
<CursorPos X="8" Y="35"/>
<UsageCount Value="10"/>
</Unit46>
<Unit47>
</Unit47>
<Unit48>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\application.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="966"/>
<CursorPos Y="981"/>
<UsageCount Value="10"/>
</Unit47>
<Unit48>
</Unit48>
<Unit49>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\SpaceEngine\uengFrameLimiter.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="14"/>
<CursorPos X="13" Y="14"/>
<UsageCount Value="10"/>
</Unit48>
<Unit49>
</Unit49>
<Unit50>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<UnitName Value="TextSuiteClasses"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="2"/>
<WindowIndex Value="1"/>
<TopLine Value="2184"/>
<CursorPos X="3" Y="2192"/>
<UsageCount Value="12"/>
<TopLine Value="1811"/>
<CursorPos X="18" Y="1754"/>
<UsageCount Value="17"/>
<Loaded Value="True"/>
</Unit49>
<Unit50>
</Unit50>
<Unit51>
<Filename Value="..\..\old\TextSuite.pas"/>
<UnitName Value="TextSuite"/>
<EditorIndex Value="3"/>
<EditorIndex Value="9"/>
<WindowIndex Value="1"/>
<TopLine Value="1293"/>
<CursorPos X="44" Y="1298"/>
<UsageCount Value="11"/>
<TopLine Value="29"/>
<CursorPos X="3" Y="45"/>
<UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit50>
<Unit51>
</Unit51>
<Unit52>
<Filename Value="..\..\old\TextSuiteWideUtils.pas"/>
<UnitName Value="TextSuiteWideUtils"/>
<EditorIndex Value="4"/>
<EditorIndex Value="10"/>
<WindowIndex Value="1"/>
<TopLine Value="1362"/>
<CursorPos X="3" Y="1390"/>
<UsageCount Value="11"/>
<UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit51>
<Unit52>
</Unit52>
<Unit53>
<Filename Value="..\..\utsWideStringUtils.pas"/>
<EditorIndex Value="-1"/>
<CursorPos Y="9"/>
<UsageCount Value="20"/>
</Unit52>
</Unit53>
<Unit54>
<Filename Value="..\..\old\TextSuiteCPUUtils.pas"/>
<UnitName Value="TextSuiteCPUUtils"/>
<EditorIndex Value="3"/>
<WindowIndex Value="1"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit54>
<Unit55>
<Filename Value="..\..\old\TextSuiteImports.pas"/>
<UnitName Value="TextSuiteImports"/>
<EditorIndex Value="4"/>
<WindowIndex Value="1"/>
<CursorPos X="41" Y="12"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit55>
<Unit56>
<Filename Value="..\..\old\TextSuiteOptions.inc"/>
<EditorIndex Value="5"/>
<WindowIndex Value="1"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit56>
<Unit57>
<Filename Value="..\..\old\TextSuitePostProcess.pas"/>
<UnitName Value="TextSuitePostProcess"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="6"/>
<WindowIndex Value="1"/>
<TopLine Value="261"/>
<CursorPos X="23" Y="345"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit57>
<Unit58>
<Filename Value="..\..\old\TextSuiteTTFUtils.pas"/>
<UnitName Value="TextSuiteTTFUtils"/>
<EditorIndex Value="7"/>
<WindowIndex Value="1"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit58>
<Unit59>
<Filename Value="..\..\old\TextSuiteVersion.pas"/>
<UnitName Value="TextSuiteVersion"/>
<EditorIndex Value="8"/>
<WindowIndex Value="1"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit59>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<JumpHistory Count="29" HistoryIndex="28">
<Position1>
<Filename Value="..\..\utsTypes.pas"/>
<Caret Line="190" TopLine="172"/>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="878" TopLine="866"/>
</Position1>
<Position2>
<Filename Value="..\..\utsTypes.pas"/>
<Caret Line="191" TopLine="172"/>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="879" TopLine="866"/>
</Position2>
<Position3>
<Filename Value="..\..\utsTypes.pas"/>
<Caret Line="192" TopLine="172"/>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="880" TopLine="866"/>
</Position3>
<Position4>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="54" Column="14" TopLine="39"/>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="371" Column="23" TopLine="358"/>
</Position4>
<Position5>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="475" Column="20" TopLine="466"/>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="394" Column="68" TopLine="367"/>
</Position5>
<Position6>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="471" TopLine="465"/>
<Caret Line="882" Column="44" TopLine="866"/>
</Position6>
<Position7>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="472" TopLine="465"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="87" Column="69" TopLine="71"/>
</Position7>
<Position8>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="511" TopLine="495"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="65" Column="65" TopLine="38"/>
</Position8>
<Position9>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="515" Column="27" TopLine="495"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="243" Column="46" TopLine="223"/>
</Position9>
<Position10>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="512" Column="27" TopLine="496"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="240" Column="34" TopLine="224"/>
</Position10>
<Position11>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="471" TopLine="455"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="35" Column="15" TopLine="25"/>
</Position11>
<Position12>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="511" TopLine="495"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="91" Column="73" TopLine="71"/>
</Position12>
<Position13>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="519" Column="38" TopLine="495"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="234" Column="19" TopLine="219"/>
</Position13>
<Position14>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="513" TopLine="495"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="241" TopLine="222"/>
</Position14>
<Position15>
<Filename Value="..\..\utsTypes.pas"/>
<Caret Line="237" TopLine="221"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="246" TopLine="222"/>
</Position15>
<Position16>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="554" Column="44" TopLine="532"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="242" TopLine="222"/>
</Position16>
<Position17>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="536" Column="33" TopLine="520"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="245" TopLine="222"/>
</Position17>
<Position18>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="730" Column="14" TopLine="718"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="244" TopLine="222"/>
</Position18>
<Position19>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="243" TopLine="222"/>
</Position19>
<Position20>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="43" Column="9" TopLine="28"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="242" TopLine="222"/>
</Position20>
<Position21>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="44" Column="32" TopLine="28"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="241" Column="36" TopLine="225"/>
</Position21>
<Position22>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="70" Column="16" TopLine="53"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="243" Column="56" TopLine="229"/>
</Position22>
<Position23>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="158" Column="9" TopLine="144"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="248" TopLine="227"/>
</Position23>
<Position24>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<Caret Line="1978" Column="3" TopLine="1973"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="250" Column="80" TopLine="228"/>
</Position24>
<Position25>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<Caret Line="108" Column="32" TopLine="84"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="248" Column="28" TopLine="233"/>
</Position25>
<Position26>
<Filename Value="uMainForm.pas"/>
<Caret Line="135" Column="20" TopLine="118"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="250" Column="48" TopLine="233"/>
</Position26>
<Position27>
<Filename Value="uMainForm.pas"/>
<Caret Line="133" Column="31" TopLine="118"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="225" Column="3" TopLine="217"/>
</Position27>
<Position28>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="252" Column="19" TopLine="232"/>
<Filename Value="..\..\utsPostProcess.pas"/>
<Caret Line="246" Column="34" TopLine="228"/>
</Position28>
<Position29>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="2128" Column="19" TopLine="2111"/>
<Filename Value="uMainForm.pas"/>
<Caret Line="91" Column="73" TopLine="71"/>
</Position29>
<Position30>
<Filename Value="..\..\utsTextSuite.pas"/>
<Caret Line="1759" Column="52" TopLine="1743"/>
</Position30>
</JumpHistory>
</ProjectSession>
<Debugging>
<BreakPoints Count="2">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="..\..\utsTypes.pas"/>
<Line Value="263"/>
</Item1>
<Item2>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="..\..\utsTypes.pas"/>
<Line Value="272"/>
</Item2>
</BreakPoints>
<Watches Count="3">
<Item1>
<Expression Value="aItem"/>


+ 28
- 7
examples/simple/uMainForm.pas View File

@@ -8,7 +8,7 @@ interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, uglcContext, TextSuite, uglcTypes,
utsTextSuite, utsTypes, utsFontCreatorGDI, utsRendererOpenGL;
utsTextSuite, utsTypes, utsFontCreatorGDI, utsRendererOpenGL, utsPostProcess;

type
TMainForm = class(TForm)
@@ -53,6 +53,18 @@ const
procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
pp: TtsPostProcessStep;
pa: TtsImage;
const
data: array[0..63] of Byte = (
$FF, $AA, $88, $44, $44, $88, $AA, $FF,
$AA, $88, $44, $22, $22, $44, $88, $AA,
$88, $44, $22, $11, $11, $22, $44, $88,
$44, $22, $11, $00, $00, $11, $22, $44,
$44, $22, $11, $00, $00, $11, $22, $44,
$88, $44, $22, $11, $11, $22, $44, $88,
$AA, $88, $44, $22, $22, $44, $88, $AA,
$FF, $AA, $88, $44, $44, $88, $AA, $FF);
begin
pf := TglcContext.MakePF();
fContext := TglcContext.GetPlatformClass.Create(self, pf);
@@ -67,9 +79,18 @@ begin
tsFontBind(ftsFont);
{$ELSE}
ftsContext := TtsContext.Create;
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatAlpha8);
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatRGBA8);
ftsGenerator := TtsFontGeneratorGDI.Create(ftsContext);
ftsFont1 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 25, [tsStyleBold, tsStyleItalic], tsAANormal);

pp := TtsPostProcessFillColor.Create(tsColor4f(0.0, 0.0, 0.0, 1.0), TS_MODES_MODULATE_ALPHA, TS_CHANNELS_RGBA);
pp.AddUsageRange(tsUsageInclude, #$0000, #$FFFF);
ftsGenerator.AddPostProcessStep(pp);

pp := TtsPostProcessShadow.Create(3, 0, 2, 2, tsColor4f(1.0, 0.0, 1.0, 0.05));
pp.AddUsageRange(tsUsageInclude, #$0000, #$FFFF);
ftsGenerator.AddPostProcessStep(pp);

ftsFont1 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 100, [tsStyleBold, tsStyleItalic], tsAANormal);
ftsFont2 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 20, [], tsAANormal);
{$ENDIF}
end;
@@ -113,7 +134,7 @@ begin
fFrameTime := t;

glViewport(0, 0, ClientWidth, ClientHeight);
glClearColor(0, 0, 0, 0);
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
@@ -123,7 +144,7 @@ begin
glLoadIdentity;

glEnable(GL_BLEND);
glcBlendFunc(TglcBlendMode.bmAdditiveAlphaBlend);
glcBlendFunc(TglcBlendMode.bmAlphaBlend);

{$IFDEF USE_OLD_TS}
tsTextBeginBlock(0, 0, ClientWidth, ClientHeight, TS_ALIGN_BLOCK);
@@ -135,7 +156,7 @@ begin
block.HorzAlign := tsHorzAlignJustify;

block.ChangeFont(ftsFont1);
block.ChangeColor(tsColor4f(1.0, 0.0, 0.0, 1.0));
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutW('L');

block.ChangeFont(ftsFont2);
@@ -143,7 +164,7 @@ begin
block.TextOutW(TEST_STRING + sLineBreak);

block.ChangeFont(ftsFont1);
block.ChangeColor(tsColor4f(0.0, 1.0, 0.0, 1.0));
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutW('L');

block.ChangeFont(ftsFont2);


+ 261
- 0
utsPostProcess.pas View File

@@ -0,0 +1,261 @@
unit utsPostProcess;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, utsTextSuite, utsTypes;

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TtsPostProcessFillColor = class(TtsPostProcessStep)
private
fColor: TtsColor4f;
fModes: TtsImageModes;
fChannels: TtsColorChannels;
protected
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
public
constructor Create(const aColor: TtsColor4f;
const aModes: TtsImageModes; const aChannels: TtsColorChannels);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TtsPostProcessFillPattern = class(TtsPostProcessStep)
private
fPattern: TtsImage;
fOwnsPattern: Boolean;
fX, fY: Integer;
fModes: TtsImageModes;
fChannels: TtsColorChannels;
protected
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
public
constructor Create(const aPattern: TtsImage; const aOwnsPattern: Boolean; const X, Y: Integer;
const aModes: TtsImageModes; const aChannels: TtsColorChannels);
destructor Destroy; override;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TtsPostProcessBorder = class(TtsPostProcessStep)
private
fKernel: TtsKernel2D;
fColor: TtsColor4f;
fUpdateCharSize: Boolean;
public
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
public
constructor Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
const aUpdateCharSize: Boolean = false);
destructor Destroy; override;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TtsPostProcessShadow = class(TtsPostProcessStep)
private
fKernel: TtsKernel1D;
fColor: TtsColor4f;
fX, fY: Integer;
protected
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
public
constructor Create(const aRadius, aStrength: Single; const X, Y: Integer; const aColor: TtsColor4f);
destructor Destroy; override;
end;

implementation

uses
Math;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsPostProcessFillColor///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsPostProcessFillColor.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
begin
if Assigned(aCharImage) then
aCharImage.FillColor(fColor, fChannels, fModes);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsPostProcessFillColor.Create(const aColor: TtsColor4f; const aModes: TtsImageModes; const aChannels: TtsColorChannels);
begin
inherited Create;
fColor := aColor;
fModes := aModes;
fChannels := aChannels;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsPostProcessFillPattern/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsPostProcessFillPattern.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
begin
if Assigned(aCharImage) then
aCharImage.FillPattern(fPattern, fX, fY, fChannels, fModes);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsPostProcessFillPattern.Create(const aPattern: TtsImage; const aOwnsPattern: Boolean; const X,
Y: Integer; const aModes: TtsImageModes; const aChannels: TtsColorChannels);
begin
inherited Create;
fPattern := aPattern;
fOwnsPattern := aOwnsPattern;
fX := X;
fY := Y;
fModes := aModes;
fChannels := aChannels;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TtsPostProcessFillPattern.Destroy;
begin
if fOwnsPattern then
FreeAndNil(fPattern);
inherited Destroy;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsPostProcessBorder//////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsPostProcessBorder.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
var
orig: TtsImage;
x, y: Integer;
dst: PByte;

function BorderLookup: TtsColor4f;
var
i: Integer;
c: TtsColor4f;
s: Single;
chan: TtsColorChannel;
mask: TtsColorChannels;
tmpX, tmpY: Integer;
begin
mask := TS_CHANNELS_RGBA;
result := tsColor4f(0, 0, 0, 0);
for i := 0 to fKernel.ItemCount-1 do begin
tmpX := x + fKernel.Items[i].OffsetX;
tmpY := y + fKernel.Items[i].OffsetY;
if (tmpX >= 0) and (tmpX < orig.Width) and
(tmpY >= 0) and (tmpY < orig.Height) and
orig.GetPixelAt(tmpX, tmpY, c) then
begin
for chan in mask do begin
s := c.arr[Integer(chan)] * fColor.arr[Integer(chan)] * fKernel.Items[i].Value;
if (s > result.arr[Integer(chan)]) then begin
result.arr[Integer(chan)] := s;
if (s >= 1.0) then begin
Exclude(mask, chan);
if (mask = []) then
exit;
end;
end;
end;
end;
end;
end;

begin
if not Assigned(aCharImage) then
exit;

aCharImage.Resize(
aCharImage.Width + 2 * fKernel.SizeX,
aCharImage.Height + 2 * fKernel.SizeY,
fKernel.SizeX, fKernel.SizeY);

orig := TtsImage.Create;
try
orig.Assign(aCharImage);
aCharImage.FillColor(fColor, TS_CHANNELS_RGBA, TS_MODES_REPLACE_ALL);

for y := 0 to orig.Height-1 do begin
dst := aCharImage.Scanline[y];
for x := 0 to orig.Width-1 do
tsFormatMap(aCharImage.Format, dst, BorderLookup);
end;

aCharImage.Blend(orig, 0, 0, @tsBlendFundAdditiveAlpha);
finally
FreeAndNil(orig);
end;

if fUpdateCharSize then begin
aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX,
aChar.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY,
aChar.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX,
aChar.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY);
aChar.GlyphOrigin := tsPosition(
aChar.GlyphOrigin.x + fKernel.MidSizeX,
aChar.GlyphOrigin.y + fKernel.MidSizeY);
aChar.Advance := aChar.Advance + fKernel.MidSizeX ;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsPostProcessBorder.Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
const aUpdateCharSize: Boolean);
begin
inherited Create;
fKernel := TtsKernel2D.Create(aWidth, aStrength);
fColor := aColor;
fUpdateCharSize := aUpdateCharSize;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TtsPostProcessBorder.Destroy;
begin
FreeAndNil(fKernel);
inherited Destroy;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsPostProcessShadow//////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsPostProcessShadow.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
var
orig: TtsImage;
tmpX, tmpY: Integer;
begin
orig := TtsImage.Create;
try
orig.Assign(aCharImage);
aCharImage.Resize(
aCharImage.Width + 2 * fKernel.Size,
aCharImage.Height + 2 * fKernel.Size,
fKernel.Size, fKernel.Size);
aCharImage.FillColor(fColor, TS_CHANNELS_RGBA, TS_MODES_MODULATE_ALPHA);
aCharImage.Blur(fKernel, fKernel, [tsChannelAlpha]);

tmpX := fKernel.Size - fX;
tmpY := fKernel.Size - fY;
aCharImage.Blend(orig, tmpX, tmpY, @tsBlendFundAlpha);
finally
FreeAndNil(orig);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsPostProcessShadow.Create(const aRadius, aStrength: Single; const X, Y: Integer; const aColor: TtsColor4f);
begin
inherited Create;
fKernel := TtsKernel1D.Create(aRadius, aStrength);
fX := X;
fY := Y;
fColor := aColor;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TtsPostProcessShadow.Destroy;
begin
FreeAndNil(fKernel);
inherited Destroy;
end;

end.


+ 4
- 0
utsRendererOpenGL.pas View File

@@ -107,6 +107,10 @@ const
( //tsFormatAlpha8
InternalFormat: GL_ALPHA8;
Format: GL_ALPHA;
DataFormat: GL_UNSIGNED_BYTE),
( //tsFormatAlpha8
InternalFormat: GL_LUMINANCE8;
Format: GL_LUMINANCE;
DataFormat: GL_UNSIGNED_BYTE)
);



+ 211
- 136
utsTextSuite.pas View File

@@ -19,7 +19,6 @@ type
TtsKernel1DItem = packed record
Offset: Integer;
Value: Single;
DataOffset: Integer;
end;

TtsKernel1D = class
@@ -30,11 +29,36 @@ type
constructor Create(const aRadius, aStrength: Single);
end;

TtsKernel2DItem = packed record
OffsetX: Integer;
OffsetY: Integer;
Value: Double;
DataOffset: Integer;
end;

TtsKernel2D = class
public
SizeX: Integer;
SizeY: Integer;

MidSizeX: Integer;
MidSizeY: Integer;

ValueSum: Double;

Items: array of TtsKernel2DItem;
ItemCount: Integer;

constructor Create(const aRadius, aStrength: Single);
end;

TtsImageFunc = procedure(const aImage: TtsImage; X, Y: Integer; var aPixel: TtsColor4f; aArgs: Pointer);
TtsImage = class(TObject)
private
fWidth: Integer;
fHeight: Integer;
fDataSize: Integer;
fLineSize: Integer;
fFormat: TtsFormat;

fData: Pointer;
@@ -43,14 +67,18 @@ type

function GetScanline(const aIndex: Integer): Pointer;
function GetIsEmpty: Boolean;
procedure SetData(const aData: Pointer; const aFormat: TtsFormat = tsFormatEmpty; const aWidth: Integer = 0; const aHeight: Integer = 0);
procedure SetData(const aData: Pointer; const aFormat: TtsFormat = tsFormatEmpty;
const aWidth: Integer = 0; const aHeight: Integer = 0;
const aLineSize: Integer = 0; const aDataSize: Integer = 0);
procedure UpdateScanlines;
public
property IsEmpty: Boolean read GetIsEmpty;
property Width: Integer read fWidth;
property Height: Integer read fHeight;
property Format: TtsFormat read fFormat;
property Data: Pointer read fData;
property IsEmpty: Boolean read GetIsEmpty;
property Width: Integer read fWidth;
property Height: Integer read fHeight;
property LineSize: Integer read fLineSize;
property DataSize: Integer read fDataSize;
property Format: TtsFormat read fFormat;
property Data: Pointer read fData;
property Scanline[const aIndex: Integer]: Pointer read GetScanline;

function GetPixelAt(const x, y: Integer; out aColor: TtsColor4f): Boolean;
@@ -64,7 +92,7 @@ type

procedure FillColor(const aColor: TtsColor4f; const aChannelMask: TtsColorChannels; const aModes: TtsImageModes);
procedure FillPattern(const aPattern: TtsImage; X, Y: Integer; const aChannelMask: TtsColorChannels; const aModes: TtsImageModes);
procedure BlendImage(const aImage: TtsImage; const X, Y: Integer);
procedure Blend(const aImage: TtsImage; const X, Y: Integer; const aFunc: TtsBlendFunc);
procedure Blur(const aHorzKernel, aVertKernel: TtsKernel1D; const aChannelMask: TtsColorChannels);

procedure AddResizingBorder;
@@ -159,9 +187,10 @@ type
fExcludeCharRange: TList;

procedure ClearList(const aList: TList);
protected
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); virtual; abstract;
public
function IsInRange(const aCharCode: WideChar): Boolean;
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); virtual; abstract;

procedure AddUsageRange(const aUsage: TtsFontProcessStepUsage; const aStartChar, aEndChar: WideChar);
procedure AddUsageChars(const aUsage: TtsFontProcessStepUsage; aChars: PWideChar);
@@ -464,6 +493,116 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsKernel2D///////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsKernel2D.Create(const aRadius, aStrength: Single);
var
tmpStrenght: Double;
tmpRadius: Double;
tmpValue: Double;
sqrRadius: Double;
x, y, w, h: Integer;

function CalcValue(const aIndex: Double): Double;
begin
result := max(0, Abs(aIndex) - tmpStrenght);
result := Sqr(result * tmpRadius) / sqrRadius;
result := Exp(-result);
end;

procedure CalcSize(var aSize, aMidSize: Integer);
begin
aSize := 0;
aMidSize := 0;
while CalcValue(aSize) > 0.5 do begin
inc(aSize, 1);
inc(aMidSize, 1);
end;
while CalcValue(aSize) > 0.001 do
Inc(aSize, 1);
end;

procedure SetItem(const x, y: Integer);
begin
with Items[(SizeY + y) * w + (SizeX + x)] do begin
OffsetX := x;
OffsetY := y;
Value := tmpValue;
end;
end;

procedure QuickSort(l, r: Integer);
var
_l, _r: Integer;
p, t: TtsKernel2DItem;
begin
repeat
_l := l;
_r := r;
p := Items[(l + r) shr 1];

repeat
while (Items[_l].Value > p.Value) do
inc(_l, 1);

while (Items[_r].Value < p.Value) do
dec(_r, 1);

if (_l <= _r) then begin
t := Items[_l];
Items[_l] := Items[_r];
Items[_r] := t;
inc(_l, 1);
dec(_r, 1);
end;
until (_l > _r);

if (l < _r) then
QuickSort(l, _r);

l := _l;
until (_l >= r);
end;

begin
inherited Create;

tmpStrenght := Min(aRadius - 1.0, aRadius * aStrength);
tmpRadius := aRadius - tmpStrenght;
sqrRadius := sqr(tmpRadius) * sqr(tmpRadius);

CalcSize(SizeX, MidSizeX);
CalcSize(SizeY, MidSizeY);

ValueSum := 0.0;
w := 2 * SizeX + 1;
h := 2 * SizeY + 1;
ItemCount := w * h;
SetLength(Items, ItemCount);

for y := 0 to SizeY do begin
for x := 0 to SizeX do begin
tmpValue := CalcValue(sqrt(Sqr(x) + Sqr(y)));

SetItem( x, y);
SetItem( x, -y);
SetItem(-x, -y);
SetItem(-x, y);

ValueSum := ValueSum + tmpValue;
if (x > 0) and (y > 0) then
ValueSum := ValueSum + tmpValue;
end;
end;

QuickSort(0, ItemCount-1);

while (Items[ItemCount-1].Value < 0.001) do
dec(ItemCount, 1);
SetLength(Items, ItemCount);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TtsImage//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -485,7 +624,8 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsImage.SetData(const aData: Pointer; const aFormat: TtsFormat; const aWidth: Integer; const aHeight: Integer);
procedure TtsImage.SetData(const aData: Pointer; const aFormat: TtsFormat; const aWidth: Integer;
const aHeight: Integer; const aLineSize: Integer; const aDataSize: Integer);
begin
fHasScanlines := false;
if Assigned(fData) then
@@ -493,28 +633,30 @@ begin

fData := aData;
if Assigned(fData) then begin
fWidth := aWidth;
fHeight := aHeight;
fFormat := aFormat;
fWidth := aWidth;
fHeight := aHeight;
fFormat := aFormat;
fLineSize := aLineSize;
fDataSize := aDataSize;
end else begin
fWidth := 0;
fHeight := 0;
fFormat := tsFormatEmpty;
fWidth := 0;
fHeight := 0;
fLineSize := 0;
fDataSize := 0;
fFormat := tsFormatEmpty;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsImage.UpdateScanlines;
var
i, LineSize: Integer;
i: Integer;
tmp: PByte;
begin
LineSize := fWidth * tsFormatSize(fFormat);
LineSize := LineSize + ((4 - (LineSize mod 4)) mod 4);
SetLength(fScanlines, fHeight);
for i := 0 to fHeight-1 do begin
tmp := fData;
inc(tmp, i * LineSize);
inc(tmp, i * fLineSize);
fScanlines[i] := tmp;
end;
fHasScanlines := true;
@@ -537,27 +679,25 @@ end;
procedure TtsImage.Assign(const aImage: TtsImage);
var
ImgData: Pointer;
ImgSize, LineSize: Integer;
begin
LineSize := aImage.Width * tsFormatSize(aImage.Format);
LineSize := LineSize + ((4 - (LineSize mod 4)) mod 4);
ImgSize := LineSize * aImage.Height;
GetMem(ImgData, ImgSize);
GetMem(ImgData, aImage.DataSize);
if Assigned(ImgData) then
Move(aImage.Data, ImgData, ImgSize);
SetData(ImgData, aImage.Format, aImage.Width, aImage.Height);
Move(aImage.Data^, ImgData^, aImage.DataSize);
SetData(ImgData, aImage.Format, aImage.Width, aImage.Height, aImage.LineSize, aImage.DataSize);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsImage.CreateEmpty(const aFormat: TtsFormat; const aWidth, aHeight: Integer);
var
ImgData: PByte;
LineSize: Integer;
lSize, dSize: Integer;
begin
LineSize := aWidth * tsFormatSize(aFormat);
LineSize := LineSize + ((4 - (LineSize mod 4)) mod 4);
ImgData := AllocMem(aHeight * LineSize);
SetData(ImgData, aFormat, aWidth, aHeight);
lSize := aWidth * tsFormatSize(aFormat);
lSize := lSize + ((4 - (lSize mod 4)) mod 4);
dSize := aHeight * lSize;
ImgData := AllocMem(dSize);
FillByte(ImgData^, dSize, 0);
SetData(ImgData, aFormat, aWidth, aHeight, lSize, dSize);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -582,7 +722,7 @@ end;
procedure TtsImage.Resize(const aNewWidth, aNewHeight, X, Y: Integer);
var
ImgData: PByte;
PixSize, LineSize, ImageSize, OrgLineSize: Integer;
pSize, lSize, dSize: Integer;

src, dst: PByte;
YStart, YEnd, YPos, XStart, XEnd: Integer;
@@ -592,14 +732,14 @@ begin
exit;
end;

PixSize := tsFormatSize(Format);
LineSize := PixSize * aNewWidth;
ImageSize := LineSize * aNewHeight;
OrgLineSize := PixSize * Width;
pSize := tsFormatSize(Format);
lSize := pSize * aNewWidth;
lSize := lSize + ((4 - (lSize mod 4)) mod 4);
dSize := lSize * aNewHeight;

GetMem(ImgData, ImageSize);
GetMem(ImgData, dSize);
try
FillChar(ImgData^, ImageSize, 0);
FillChar(ImgData^, dSize, 0);

// positions
YStart := Max(0, Y);
@@ -610,16 +750,16 @@ begin
// copy data
for YPos := YStart to YEnd -1 do begin
dst := ImgData;
Inc(dst, LineSize * YPos + PixSize * XStart);
Inc(dst, lSize * YPos + pSize * XStart);

src := fData;
Inc(src, OrgLineSize * (YPos - Y) + PixSize * (XStart - X));
Inc(src, fLineSize * (YPos - Y) + pSize * (XStart - X));

Move(src^, dst^, (XEnd - XStart) * PixSize);
Move(src^, dst^, (XEnd - XStart) * pSize);
end;

// assign
SetData(ImgData, Format, aNewWidth, aNewHeight);
SetData(ImgData, Format, aNewWidth, aNewHeight, lSize, dSize);
except
FreeMem(ImgData);
end;
@@ -663,20 +803,22 @@ end;
procedure TtsImage.FillColor(const aColor: TtsColor4f; const aChannelMask: TtsColorChannels; const aModes: TtsImageModes);
var
x, y: Integer;
p: PByte;
rp, wp: PByte;
c: TtsColor4f;
ch: TtsColorChannel;
i: Integer;
begin
for y := 0 to Height-1 do begin
p := Scanline[y];
rp := Scanline[y];
wp := rp;
for x := 0 to Width-1 do begin
tsFormatUnmap(Format, p, c);
tsFormatUnmap(Format, rp, c);
for i := 0 to 3 do begin
ch := TtsColorChannel(i);
if (ch in aChannelMask) then
c.arr[i] := IMAGE_MODE_FUNCTIONS[aModes[ch]](aColor.arr[i], c.arr[i]);
end;
tsFormatMap(Format, wp, c);
end;
end;
end;
@@ -708,7 +850,7 @@ begin
end;

tmp := dst;
tsFormatUnmap(Format, src, cSrc);
tsFormatUnmap(aPattern.Format, src, cSrc);
tsFormatUnmap(Format, tmp, cDst);
for i := 0 to 3 do begin
ch := TtsColorChannel(i);
@@ -722,97 +864,30 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsImage.BlendImage(const aImage: TtsImage; const X, Y: Integer);
procedure TtsImage.Blend(const aImage: TtsImage; const X, Y: Integer; const aFunc: TtsBlendFunc);
var
_x, _y, i: Integer;
c, cOver, cUnder: TtsColor4f;
FaqOver, FaqUnder: Single;
UnionRect, IntersectRect: TtsRect;
NewSize: TtsPosition;
ImgSize: Integer;
ImgData, dst, src, pOver, pUnder: PByte;
tmpLines: array of Pointer;
begin
UnionRect := tsRect(
Min(X, 0),
Min(Y, 0),
Max(X + aImage.Width, Width),
Max(Y + aImage.Height, Height));
IntersectRect := tsRect(
Max(X, 0),
Max(Y, 0),
Min(X + aImage.Width, Width),
Min(X + aImage.Height, Height));
NewSize := tsPosition(
UnionRect.Right - UnionRect.Left,
UnionRect.Bottom - UnionRect.Top);

ImgSize := NewSize.x * NewSize.y * tsFormatSize(Format);
GetMem(ImgData, ImgSize);
try
FillByte(ImgData^, ImgSize, $00);

// temporary scanlines
SetLength(tmpLines, NewSize.y);
for _y := 0 to NewSize.y-1 do begin
tmpLines[_y] := ImgData;
inc(tmpLines[_y], _y * NewSize.y);
end;

// copy data from underlaying image
for _y := 0 to Height-1 do begin
src := Scanline[_y];
dst := tmpLines[_y - UnionRect.Top];
dec(dst, UnionRect.Left);
for _x := 0 to Width-1 do begin
dst^ := src^;
inc(src);
inc(dst);
end;
end;

// copy data from overlaying image
for _y := 0 to aImage.Height-1 do begin
src := aImage.Scanline[_y];
dst := tmpLines[_y + y - UnionRect.Top];
inc(dst, X - UnionRect.Left);
for _x := 0 to Width-1 do begin
dst^ := src^;
inc(src);
inc(dst);
end;
end;

// blend overlapped
for _y := IntersectRect.Top to IntersectRect.Bottom-1 do begin
pOver := aImage.Scanline[_y - Min(IntersectRect.Top, UnionRect.Top)];
inc(pOver, IntersectRect.Left - UnionRect.Left);

pUnder := Scanline[_y - Min(IntersectRect.Top, 0)];
inc(pUnder, IntersectRect.Left);

dst := tmpLines[_y - Min(Y, 0)];
inc(dst, IntersectRect.Left - Min(X, 0));

for _x := IntersectRect.Left to IntersectRect.Right-1 do begin
tsFormatUnmap(aImage.Format, pOver, cOver);
tsFormatUnmap(Format, pUnder, cUnder);
c.a := cOver.a + cUnder.a * (1 - cOver.a);
if (c.a > 0) then begin
FaqUnder := (cUnder.a * (1 - cOver.a)) / c.a;
FaqOver := cOver.a / c.a;
for i := 0 to 2 do
c.arr[i] := cOver.arr[i] * FaqOver + cUnder.arr[i] * FaqUnder;
end else begin
c.r := 0;
c.g := 0;
c.b := 0;
end;
tsFormatMap(Format, dst, c);
end;
_x, _y, x1, x2, y1, y2: Integer;
src, dst, tmp: PByte;
srcColor, dstColor: TtsColor4f;
srcPixelSize, dstPixelSize: Integer;
begin
x1 := Max(X, 0);
x2 := Min(X + aImage.Width , Width);
y1 := Max(Y, 0);
y2 := Min(Y + aImage.Height, Height);
srcPixelSize := tsFormatSize(aImage.Format);
dstPixelSize := tsFormatSize(Format);
for _y := y1 to y2-1 do begin
src := aImage.Scanline[_y - min(y1, y)];
dst := Scanline[_y];
inc(src, (x1 - x) * srcPixelSize);
inc(dst, x1 * dstPixelSize);
tmp := dst;
for _x := x1 to x2-1 do begin
tsFormatUnmap(aImage.Format, src, srcColor);
tsFormatUnmap( Format, dst, dstColor);
tsFormatMap(aImage.Format, tmp, aFunc(srcColor, dstColor));
end;
except
FreeMem(ImgData);
end;
end;



+ 83
- 6
utsTypes.pas View File

@@ -77,7 +77,8 @@ type
tsFormatEmpty,
tsFormatRGBA8,
tsFormatLumAlpha8,
tsFormatAlpha8);
tsFormatAlpha8,
tsFormatLum8);

TtsAntiAliasing = (
tsAANone,
@@ -168,7 +169,18 @@ type
LineSpacing: Integer;
end;

TtsBlendFunc = function(const aSrc, aDst: TtsColor4f): TtsColor4f;

const
TS_CHANNELS_RGB: TtsColorChannels = [tsChannelRed, tsChannelGreen, tsChannelBlue];
TS_CHANNELS_RGBA: TtsColorChannels = [tsChannelRed, tsChannelGreen, tsChannelBlue, tsChannelAlpha];

TS_MODES_REPLACE_ALL: TtsImageModes = (tsModeReplace, tsModeReplace, tsModeReplace, tsModeReplace);
TS_MODES_MODULATE_ALL: TtsImageModes = (tsModeModulate, tsModeModulate, tsModeModulate, tsModeModulate);
TS_MODES_MODULATE_ALPHA: TtsImageModes = (tsModeReplace, tsModeReplace, tsModeReplace, tsModeModulate);

function tsColor4f(r, g, b, a: Single): TtsColor4f;
function tsModes(r, g, b, a: TtsImageMode): TtsImageModes;
function tsRect(const l, t, r, b: Integer): TtsRect;
function tsPosition(const x, y: Integer): TtsPosition;

@@ -180,8 +192,15 @@ function tsImageModeFuncIgnore(const aSource, aDest: Single): Single;
function tsImageModeFuncReplace(const aSource, aDest: Single): Single;
function tsImageModeFuncModulate(const aSource, aDest: Single): Single;

function tsBlendFundAlpha(const aSrc, aDst: TtsColor4f): TtsColor4f;
function tsBlendFundAdditive(const aSrc, aDst: TtsColor4f): TtsColor4f;
function tsBlendFundAdditiveAlpha(const aSrc, aDst: TtsColor4f): TtsColor4f;

implementation

uses
Math;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function tsColor4f(r, g, b, a: Single): TtsColor4f;
begin
@@ -191,6 +210,15 @@ begin
result.a := a;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function tsModes(r, g, b, a: TtsImageMode): TtsImageModes;
begin
result[tsChannelRed] := r;
result[tsChannelGreen] := g;
result[tsChannelBlue] := b;
result[tsChannelAlpha] := a;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function tsRect(const l, t, r, b: Integer): TtsRect;
begin
@@ -214,6 +242,7 @@ begin
tsFormatRGBA8: result := 4;
tsFormatLumAlpha8: result := 2;
tsFormatAlpha8: result := 1;
tsFormatLum8: result := 1;
else
result := 0;
end;
@@ -228,19 +257,31 @@ begin
case aFormat of
tsFormatRGBA8: begin
for i := 0 to 3 do begin
aData^ := Trunc($FF * aColor.arr[i]);
aData^ := Trunc($FF * min(aColor.arr[i], 1.0));
inc(aData);
end;
end;

tsFormatLumAlpha8: begin
s := 0.30 * aColor.r + 0.59 * aColor.g + 0.11 * aColor.b;
aData^ := Trunc($FF * s); inc(aData);
aData^ := Trunc($FF * aColor.a); inc(aData);
s := 0.30 * min(aColor.r, 1.0) +
0.59 * min(aColor.g, 1.0) +
0.11 * min(aColor.b, 1.0);
aData^ := Trunc($FF * s);
inc(aData);
aData^ := Trunc($FF * min(aColor.a, 1.0));
inc(aData);
end;

tsFormatAlpha8: begin
aData^ := Trunc($FF * aColor.a);
aData^ := Trunc($FF * min(aColor.a, 1.0));
inc(aData);
end;

tsFormatLum8: begin
s := 0.30 * min(aColor.r, 1.0) +
0.59 * min(aColor.g, 1.0) +
0.11 * min(aColor.b, 1.0);
aData^ := Trunc($FF * s);
inc(aData);
end;
end;
@@ -275,6 +316,14 @@ begin
aColor.a := aData^ / $FF;
inc(aData);
end;

tsFormatLum8: begin
aColor.r := aData^ / $FF;
aColor.g := aData^ / $FF;
aColor.b := aData^ / $FF;
aColor.a := 1.0;
inc(aData);
end;
end;
end;

@@ -296,5 +345,33 @@ begin
result := aSource * aDest;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function tsBlendFundAlpha(const aSrc, aDst: TtsColor4f): TtsColor4f;
var
i: Integer;
begin
for i := 0 to 2 do
result.arr[i] := aSrc.arr[i] * aSrc.a + aDst.arr[i] * (1 - aSrc.a);
result.a := aSrc.a + aDst.a * (1 - aSrc.a);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function tsBlendFundAdditive(const aSrc, aDst: TtsColor4f): TtsColor4f;
var
i: Integer;
begin
for i := 0 to 3 do
result.arr[i] := aSrc.arr[i] + aDst.arr[i];
end;

function tsBlendFundAdditiveAlpha(const aSrc, aDst: TtsColor4f): TtsColor4f;
var
i: Integer;
begin
for i := 0 to 2 do
result.arr[i] := aSrc.arr[i] * aSrc.a + aDst.arr[i];
result.a := aDst.a;
end;

end.


Loading…
Cancel
Save