gegl_drawelement.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {
  2. * Copyright (c) 2021 SSW
  3. *
  4. * This software is provided 'as-is', without any express or
  5. * implied warranty. In no event will the authors be held
  6. * liable for any damages arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute
  10. * it freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented;
  13. * you must not claim that you wrote the original software.
  14. * If you use this software in a product, an acknowledgment
  15. * in the product documentation would be appreciated but
  16. * is not required.
  17. *
  18. * 2. Altered source versions must be plainly marked as such,
  19. * and must not be misrepresented as being the original software.
  20. *
  21. * 3. This notice may not be removed or altered from any
  22. * source distribution.
  23. }
  24. unit gegl_drawElement;
  25. {$I zgl_config.cfg}
  26. interface
  27. uses
  28. zgl_font,
  29. zgl_types,
  30. {$IfDef USE_GLES}
  31. zgl_opengles_all,
  32. {$Else}
  33. zgl_opengl_all,
  34. {$EndIf}
  35. zgl_gltypeconst,
  36. zgl_window,
  37. gegl_Types,
  38. gegl_VElements,
  39. gegl_color,
  40. zgl_fx,
  41. zgl_primitives_2d,
  42. zgl_render_2d;
  43. // подготовка к выводу текста поля ввода, а так же созданной пользователем процедуры вывода окантовки поля ввода
  44. procedure EditDraw(num: Word);
  45. // вывод текста поля ввода, при выходе за пределы поля, производится обрезание текста.
  46. procedure DrawTextEdit(Edit: geglPEdit);
  47. implementation
  48. procedure EditDraw(num: Word);
  49. var
  50. UseText: geglPEdit;
  51. begin
  52. UseText := managerSetOfTools.SetOfTools[num];
  53. (* В данном случае надо обратить внимание, что все трансформации должны быть произведены "по умолчанию" -
  54. ротация, шкала, трансляция.
  55. Получается, для поля ввода, должнен быть определён фонт, который не должен меняться, но пользователь
  56. может сам выбирать этот фонт, либо просто переименовывать свой фонт, в нужное название.
  57. На данное время, работа с разными фонтами, даже менеджера не будет реализовано. Возможно в дальнейшем
  58. будет реализовано. *)
  59. // batch2d_Begin;
  60. (* при включении batch2d получаем "весёлый" эффект, когда поле ввода может быть в другом месте, и в нужном. И перемигиваться этими полями. *)
  61. glPushMatrix;
  62. // устанавливаем центр вращения
  63. glTranslatef(UseText^.RotatePoint.X, UseText^.RotatePoint.Y, 0);
  64. // поворачиваем
  65. glRotatef(UseText^.Rotate, 0, 0, 1);
  66. // и возвращаем на начальное значение рисования, только уже повернули
  67. glTranslatef(UseText^.Rect.X - UseText^.RotatePoint.x, UseText^.Rect.Y - UseText^.RotatePoint.Y, 0);
  68. // функция вывода окантовки, если её задали
  69. if Assigned(UseText^.procDraw) then
  70. UseText^.procDraw(@UseText^.Rect);
  71. // трансляция для вывода текста
  72. glTranslatef(- UseText^.translateX, 0, 0);
  73. //--------------------------------------------------------------
  74. if UseText^.EditString.UseLen > 0 then
  75. begin
  76. Set_ToNumColor(UseText^.ColorText);
  77. batch2d_Begin;
  78. DrawTextEdit(UseText);
  79. batch2d_End;
  80. end;
  81. // рисуем курсор, только если этот элемент активирован
  82. if managerSetOfTools.ActiveElement = num then
  83. if UseText^.Cursor.NSleep > 0 then
  84. begin
  85. if UseText^.Cursor.Flags then // проверяем что прорисовывать (флаг мигания)
  86. begin // и для знака подчёркивания
  87. pr2d_Rect(UseText^.Cursor.curRect.X, UseText^.Cursor.curRect.Y, UseText^.Cursor.curRect.W,
  88. UseText^.Cursor.curRect.H, UseText^.ColorCursor, PR2D_FILL);
  89. end;
  90. dec(UseText^.Cursor.NSleep);
  91. end
  92. else begin
  93. UseText^.Cursor.NSleep := 15;
  94. UseText^.Cursor.Flags := not (UseText^.Cursor.Flags);
  95. end;
  96. //--------------------------------------------------------------
  97. glPopMatrix;
  98. // batch2d_End;
  99. UseText := nil;
  100. end;
  101. // в данном варианте так, но надо всё будет переделать - размер шрифта идёт по умолчанию
  102. // задача: производить вывод только тех символов, которые попадают в поле ввода
  103. // подзадача: произвести текстурную выборку для символов, которые должны "резаться" - которые попадают на стык поля ввода
  104. procedure DrawTextEdit(Edit: geglPEdit);
  105. var
  106. i: LongWord;
  107. charDesc: zglPCharDescSmall;
  108. lastPage: Integer;
  109. XLoop, YLoop: Single;
  110. xx1, xx2, yy1, yy2: Single;
  111. xTex1, yTex1, xTex2, yTex2: Single;
  112. useFont: zglPFont;
  113. mode: LongWord;
  114. Padding: array[0..3] of Single;
  115. MaxHeight: Single;
  116. label
  117. StartLoop, EndLoop, NextLoop;
  118. begin
  119. // color??? // это должно происходить от менеджера!!! Но пока это только поле ввода, оставлю
  120. // glColor4fv(@Edit^.ColorText);
  121. if managerSetOfTools.count = 0 then
  122. exit;
  123. useFont := managerFont.Font[Edit^.font];
  124. i := 0;
  125. lastPage := -1;
  126. XLoop := 0;
  127. YLoop := - useFont^.MaxShiftY * Edit^.Scale;// useFont^.Scale;
  128. // надо определиться, нужен этот код или нет
  129. // charDesc := managerFont.Font[Edit^.font].CharDesc[Edit^.EditString.LineString[i]^.CharSymb];
  130. { charDesc := useFont^.CharDesc[Edit^.EditString.CharSymb[i]];
  131. if not b2dStarted Then // этот код нужен, когда мы закончили рисовать через glEnd, а bSize не обнулился
  132. begin // и в следующий момент, мы можем получить наложение двух разных элементов.
  133. if Assigned(charDesc) Then // это надо проверить при выводе текста. Сработало обнуление или нет.
  134. begin
  135. lastPage := charDesc^.Page;
  136. batch2d_Check(GL_QUADS, FX_BLEND, managerFont.Font[Edit^.font].Pages[lastPage]);
  137. glEnable(GL_BLEND);
  138. glEnable(GL_TEXTURE_2D);
  139. glBindTexture(GL_TEXTURE_2D, managerFont.Font[Edit^.font].Pages[lastPage]^.ID);
  140. glBegin(GL_QUADS);
  141. end else
  142. begin
  143. glEnable(GL_BLEND);
  144. glEnable(GL_TEXTURE_2D);
  145. glBegin(GL_QUADS);
  146. end;
  147. end; }
  148. MaxHeight := useFont^.MaxHeight;
  149. Padding[PaddingX1] := useFont^.Padding[PaddingX1];
  150. Padding[PaddingX2] := useFont^.Padding[PaddingX2];
  151. Padding[PaddingY1] := useFont^.Padding[PaddingY1];
  152. Padding[PaddingY2] := useFont^.Padding[PaddingY2];
  153. StartLoop:
  154. if Edit^.EditString.CharSymb[i] = 0 then
  155. goto EndLoop;
  156. charDesc := Edit^.CharDesc[Edit^.EditString.CharSymb[i]];
  157. if not Assigned(charDesc) Then
  158. charDesc := Edit^.CharDesc[63];
  159. XLoop := Edit^.EditString.posX[i];
  160. xx1 := XLoop + charDesc^.xx1;
  161. xx2 := XLoop + charDesc^.xx2;
  162. // xx1 := XLoop + (charDesc^.ShiftX - Padding[PaddingX1]) * Edit^.Scale;
  163. // xx2 := XLoop + (charDesc^.ShiftX + charDesc^.Width + Padding[PaddingX2]) * Edit^.Scale;
  164. xTex1 := charDesc^.TexCoords[0].X;
  165. xTex2 := charDesc^.TexCoords[1].X;
  166. if xx1 > Edit^.translateX + Edit^.Rect.W then
  167. goto EndLoop; // выходим, если координата за пределами
  168. if xx2 < Edit^.translateX then
  169. goto NextLoop; // переходим на следующий символ, если ещё не в пределах поля ввода
  170. // вариант когда начали писать, но текст ещё пока находится
  171. if xx1 < Edit^.translateX then
  172. begin // за пределами поля ввода
  173. xTex1 := xTex2 - (xx2 - Edit^.translateX) * (xTex2 - xTex1) / (xx2 - xx1); // или делать пересчёт координат текстуры...
  174. xx1 := Edit^.translateX;
  175. end;
  176. // и вариант, когда уже за пределами поля ввода
  177. if xx2 > Edit^.translateX + Edit^.Rect.W then
  178. begin
  179. xTex2 := xTex2 - (xx2 - Edit^.translateX - Edit^.Rect.W) * (xTex2 - xTex1) / (xx2 - xx1); // формула не меняется, меняется текстурная координата
  180. xx2 := Edit^.translateX + Edit^.Rect.W;
  181. end;
  182. // ниже код, для смены текстуры, если она разбита на части (смена страницы текстуры)
  183. if lastPage <> charDesc^.Page Then
  184. begin
  185. lastPage := charDesc^.Page;
  186. if (not b2dStarted) Then
  187. begin
  188. glEnd();
  189. glEnable(GL_BLEND);
  190. glEnable(GL_TEXTURE_2D);
  191. glBindTexture(GL_TEXTURE_2D, useFont^.Pages[lastPage]^.ID);
  192. glBegin(GL_QUADS);
  193. end else
  194. if batch2d_Check(GL_QUADS, FX_BLEND, useFont^.Pages[lastPage]) Then
  195. begin
  196. glEnable(GL_BLEND);
  197. glEnable(GL_TEXTURE_2D);
  198. glBindTexture(GL_TEXTURE_2D, useFont^.Pages[lastPage]^.ID);
  199. glBegin(GL_QUADS);
  200. end;
  201. end;
  202. yTex1 := charDesc^.TexCoords[2].Y;
  203. yTex2 := charDesc^.TexCoords[0].Y;
  204. yy1 := YLoop + charDesc^.yy1;
  205. yy2 := YLoop + charDesc^.yy2;
  206. // yy1 := YLoop + (charDesc^.ShiftY + MaxHeight - charDesc^.Height - Padding[PaddingY1]) * Edit^.Scale;
  207. // yy2 := YLoop + (charDesc^.ShiftY + MaxHeight + Padding[PaddingY2]) * Edit^.Scale;
  208. glTexCoord2f(xTex1, yTex2);
  209. glVertex2f(xx1, yy1);
  210. glTexCoord2f(xTex2, yTex2);
  211. glVertex2f(xx2, yy1);
  212. glTexCoord2f(xTex2, yTex1);
  213. glVertex2f(xx2, yy2);
  214. glTexCoord2f(xTex1, yTex1);
  215. glVertex2f(xx1, yy2);
  216. NextLoop:
  217. inc(i);
  218. if i < MAX_SYMBOL_LINE then
  219. goto StartLoop;
  220. EndLoop:
  221. if not b2dStarted Then
  222. begin
  223. glEnd();
  224. glDisable(GL_TEXTURE_2D);
  225. glDisable(GL_BLEND);
  226. end;
  227. end;
  228. end.