textElement.test.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import { getLineHeight } from "@excalidraw/common";
  2. import { API } from "@excalidraw/excalidraw/tests/helpers/api";
  3. import { FONT_FAMILY } from "@excalidraw/common";
  4. import {
  5. computeContainerDimensionForBoundText,
  6. getContainerCoords,
  7. getBoundTextMaxWidth,
  8. getBoundTextMaxHeight,
  9. } from "../src/textElement";
  10. import { detectLineHeight, getLineHeightInPx } from "../src/textMeasurements";
  11. import type { ExcalidrawTextElementWithContainer } from "../src/types";
  12. describe("Test measureText", () => {
  13. describe("Test getContainerCoords", () => {
  14. const params = { width: 200, height: 100, x: 10, y: 20 };
  15. it("should compute coords correctly when ellipse", () => {
  16. const element = API.createElement({
  17. type: "ellipse",
  18. ...params,
  19. });
  20. expect(getContainerCoords(element)).toEqual({
  21. x: 44.2893218813452455,
  22. y: 39.64466094067262,
  23. });
  24. });
  25. it("should compute coords correctly when rectangle", () => {
  26. const element = API.createElement({
  27. type: "rectangle",
  28. ...params,
  29. });
  30. expect(getContainerCoords(element)).toEqual({
  31. x: 15,
  32. y: 25,
  33. });
  34. });
  35. it("should compute coords correctly when diamond", () => {
  36. const element = API.createElement({
  37. type: "diamond",
  38. ...params,
  39. });
  40. expect(getContainerCoords(element)).toEqual({
  41. x: 65,
  42. y: 50,
  43. });
  44. });
  45. });
  46. describe("Test computeContainerDimensionForBoundText", () => {
  47. const params = {
  48. width: 178,
  49. height: 194,
  50. };
  51. it("should compute container height correctly for rectangle", () => {
  52. const element = API.createElement({
  53. type: "rectangle",
  54. ...params,
  55. });
  56. expect(computeContainerDimensionForBoundText(150, element.type)).toEqual(
  57. 160,
  58. );
  59. });
  60. it("should compute container height correctly for ellipse", () => {
  61. const element = API.createElement({
  62. type: "ellipse",
  63. ...params,
  64. });
  65. expect(computeContainerDimensionForBoundText(150, element.type)).toEqual(
  66. 226,
  67. );
  68. });
  69. it("should compute container height correctly for diamond", () => {
  70. const element = API.createElement({
  71. type: "diamond",
  72. ...params,
  73. });
  74. expect(computeContainerDimensionForBoundText(150, element.type)).toEqual(
  75. 320,
  76. );
  77. });
  78. });
  79. describe("Test getBoundTextMaxWidth", () => {
  80. const params = {
  81. width: 178,
  82. height: 194,
  83. };
  84. it("should return max width when container is rectangle", () => {
  85. const container = API.createElement({ type: "rectangle", ...params });
  86. expect(getBoundTextMaxWidth(container, null)).toBe(168);
  87. });
  88. it("should return max width when container is ellipse", () => {
  89. const container = API.createElement({ type: "ellipse", ...params });
  90. expect(getBoundTextMaxWidth(container, null)).toBe(116);
  91. });
  92. it("should return max width when container is diamond", () => {
  93. const container = API.createElement({ type: "diamond", ...params });
  94. expect(getBoundTextMaxWidth(container, null)).toBe(79);
  95. });
  96. });
  97. describe("Test getBoundTextMaxHeight", () => {
  98. const params = {
  99. width: 178,
  100. height: 194,
  101. id: '"container-id',
  102. };
  103. const boundTextElement = API.createElement({
  104. type: "text",
  105. id: "text-id",
  106. x: 560.51171875,
  107. y: 202.033203125,
  108. width: 154,
  109. height: 175,
  110. fontSize: 20,
  111. fontFamily: 1,
  112. text: "Excalidraw is a\nvirtual \nopensource \nwhiteboard for \nsketching \nhand-drawn like\ndiagrams",
  113. textAlign: "center",
  114. verticalAlign: "middle",
  115. containerId: params.id,
  116. }) as ExcalidrawTextElementWithContainer;
  117. it("should return max height when container is rectangle", () => {
  118. const container = API.createElement({ type: "rectangle", ...params });
  119. expect(getBoundTextMaxHeight(container, boundTextElement)).toBe(184);
  120. });
  121. it("should return max height when container is ellipse", () => {
  122. const container = API.createElement({ type: "ellipse", ...params });
  123. expect(getBoundTextMaxHeight(container, boundTextElement)).toBe(127);
  124. });
  125. it("should return max height when container is diamond", () => {
  126. const container = API.createElement({ type: "diamond", ...params });
  127. expect(getBoundTextMaxHeight(container, boundTextElement)).toBe(87);
  128. });
  129. it("should return max height when container is arrow", () => {
  130. const container = API.createElement({
  131. type: "arrow",
  132. ...params,
  133. });
  134. expect(getBoundTextMaxHeight(container, boundTextElement)).toBe(194);
  135. });
  136. it("should return max height when container is arrow and height is less than threshold", () => {
  137. const container = API.createElement({
  138. type: "arrow",
  139. ...params,
  140. height: 70,
  141. boundElements: [{ type: "text", id: "text-id" }],
  142. });
  143. expect(getBoundTextMaxHeight(container, boundTextElement)).toBe(
  144. boundTextElement.height,
  145. );
  146. });
  147. });
  148. });
  149. const textElement = API.createElement({
  150. type: "text",
  151. text: "Excalidraw is a\nvirtual \nopensource \nwhiteboard for \nsketching \nhand-drawn like\ndiagrams",
  152. fontSize: 20,
  153. fontFamily: 1,
  154. height: 175,
  155. });
  156. describe("Test detectLineHeight", () => {
  157. it("should return correct line height", () => {
  158. expect(detectLineHeight(textElement)).toBe(1.25);
  159. });
  160. });
  161. describe("Test getLineHeightInPx", () => {
  162. it("should return correct line height", () => {
  163. expect(
  164. getLineHeightInPx(textElement.fontSize, textElement.lineHeight),
  165. ).toBe(25);
  166. });
  167. });
  168. describe("Test getDefaultLineHeight", () => {
  169. it("should return line height using default font family when not passed", () => {
  170. //@ts-ignore
  171. expect(getLineHeight()).toBe(1.25);
  172. });
  173. it("should return line height using default font family for unknown font", () => {
  174. const UNKNOWN_FONT = 5;
  175. expect(getLineHeight(UNKNOWN_FONT)).toBe(1.25);
  176. });
  177. it("should return correct line height", () => {
  178. expect(getLineHeight(FONT_FAMILY.Cascadia)).toBe(1.2);
  179. });
  180. });