Vuo  2.3.2
VuoSceneText.c
Go to the documentation of this file.
1 
10 #include "VuoSceneText.h"
11 #include "VuoImageText.h"
12 #include "module.h"
13 
14 #ifdef VUO_COMPILER
16  "title" : "VuoSceneText",
17  "dependencies" : [
18  "VuoImageText",
19  "VuoSceneObject",
20  "VuoFont",
21  "VuoMesh"
22  ]
23  });
24 #endif
25 
33 {
34  unsigned int vertexCount = 4;
35  unsigned int elementCount = 6;
36 
37  float *positions, *textureCoordinates;
38  unsigned int *elements;
39  VuoMesh_allocateCPUBuffers(vertexCount, &positions, NULL, &textureCoordinates, NULL, elementCount, &elements);
40 
41  positions[0 * 3 ] = -.5;
42  positions[0 * 3 + 1] = -.5;
43  positions[0 * 3 + 2] = 0;
44  positions[1 * 3 ] = .5;
45  positions[1 * 3 + 1] = -.5;
46  positions[1 * 3 + 2] = 0;
47  positions[2 * 3 ] = -.5;
48  positions[2 * 3 + 1] = .5;
49  positions[2 * 3 + 2] = 0;
50  positions[3 * 3 ] = .5;
51  positions[3 * 3 + 1] = .5;
52  positions[3 * 3 + 2] = 0;
53 
54  textureCoordinates[0 * 2 ] = 0;
55  textureCoordinates[0 * 2 + 1] = 0;
56  textureCoordinates[1 * 2 ] = 1;
57  textureCoordinates[1 * 2 + 1] = 0;
58  textureCoordinates[2 * 2 ] = 0;
59  textureCoordinates[2 * 2 + 1] = 1;
60  textureCoordinates[3 * 2 ] = 1;
61  textureCoordinates[3 * 2 + 1] = 1;
62 
63  // Order the elements so that the diagonal edge of each triangle
64  // is last, so that vuo.shader.make.wireframe can optionally omit them.
65  elements[0] = 2;
66  elements[1] = 0;
67  elements[2] = 1;
68  elements[3] = 1;
69  elements[4] = 3;
70  elements[5] = 2;
71 
72  float horizontal = VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Left ? .5f : (VuoAnchor_getHorizontal(anchor) == VuoHorizontalAlignment_Right ? -.5f : 0.f);
73  float vertical = VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Top ? -.5f : (VuoAnchor_getVertical(anchor) == VuoVerticalAlignment_Bottom ? .5f : 0.f);
74 
75  for(int i = 0; i < vertexCount; i++)
76  {
77  positions[i * 3 ] += horizontal;
78  positions[i * 3 + 1] += vertical;
79  }
80 
81  return VuoMesh_makeFromCPUBuffers(vertexCount,
82  positions, NULL, textureCoordinates, NULL,
83  elementCount, elements, VuoMesh_IndividualTriangles);
84 }
85 
96 VuoSceneObject VuoSceneText_make(const VuoText text, const VuoFont font, const VuoBoolean scaleWithScene, const VuoReal wrapWidth, const VuoAnchor anchor)
97 {
98  VuoSceneObject so = VuoSceneObject_makeText(text, font, scaleWithScene, wrapWidth);
100  return so;
101 }
102 
108 {
109  VuoMesh mesh = VuoSceneObject_getMesh(so);
110  if (!mesh)
111  return VuoAnchor_makeCentered();
112 
113  VuoPoint2d mesh0;
114  {
115  unsigned int vertexCount;
116  float *positions;
117  VuoMesh_getCPUBuffers(mesh, &vertexCount, &positions, NULL, NULL, NULL, NULL, NULL);
118  mesh0 = (VuoPoint2d){ positions[0], positions[1] };
119  }
120 
123 
124  // (We know from VuoSceneText_make() that the mesh's first coordinate
125  // is 0.0, -0.5, or -1.0, depending on whether the anchor is left/top, center, or right/bottom, respectively.)
126  if (VuoReal_areEqual(mesh0.x, 0))
127  h = VuoHorizontalAlignment_Left;
128  else if (VuoReal_areEqual(mesh0.x, -.5))
129  h = VuoHorizontalAlignment_Center;
130  else //if (VuoReal_areEqual(mesh0.x, -1))
131  h = VuoHorizontalAlignment_Right;
132 
133  if (VuoReal_areEqual(mesh0.y, -1))
134  v = VuoVerticalAlignment_Top;
135  else if (VuoReal_areEqual(mesh0.y, -.5))
136  v = VuoVerticalAlignment_Center;
137  else //if (VuoReal_areEqual(mesh0.y, 0))
138  v = VuoVerticalAlignment_Bottom;
139 
140  return VuoAnchor_make(h, v);
141 }
142 
147 VuoPoint2d VuoSceneText_getAnchorOffset(VuoSceneObject so, float verticalScale, float rotationZ, float wrapWidth, int viewportWidth, int backingScaleFactor)
148 {
150  if (a == VuoAnchor_make(VuoHorizontalAlignment_Center, VuoVerticalAlignment_Center))
151  // Already in center.
152  return (VuoPoint2d){0, 0};
153 
154  VuoImageTextData td = VuoImage_getTextImageData(VuoSceneObject_getText(so), VuoSceneObject_getTextFont(so), backingScaleFactor, verticalScale, rotationZ, false);
155  VuoLocal(td);
156  VuoPoint2d *corners = td->transformedCorners;
157 
158  // Convert the corner pixel coodrinates to scene coordinates.
159  for (int i = 0; i < 4; ++i)
160  {
161  corners[i].x *= -2. / viewportWidth;
162  corners[i].y *= -2. / viewportWidth;
163  }
164 
165  // Move the origin to the anchor point.
166  double width = fmax(fabs(corners[2].x - corners[0].x), fabs(corners[3].x - corners[1].x));
167  double height = fmax(fabs(corners[2].y - corners[0].y), fabs(corners[3].y - corners[1].y));
168  if (a == VuoAnchor_make(VuoHorizontalAlignment_Left, VuoVerticalAlignment_Top))
169  return (VuoPoint2d){
170  corners[0].x,
171  -corners[0].y
172  };
173  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Left, VuoVerticalAlignment_Center))
174  return (VuoPoint2d){
175  (corners[0].x + corners[3].x)/2,
176  -((corners[0].y + corners[3].y)/2 + height/2.)
177  };
178  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Left, VuoVerticalAlignment_Bottom))
179  return (VuoPoint2d){
180  corners[3].x,
181  -(corners[3].y + height)
182  };
183  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Center, VuoVerticalAlignment_Top))
184  return (VuoPoint2d){
185  (corners[0].x + corners[1].x)/2 + width/2.,
186  -(corners[0].y + corners[1].y)/2
187  };
188  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Center, VuoVerticalAlignment_Bottom))
189  return (VuoPoint2d){
190  (corners[2].x + corners[3].x)/2 + width/2.,
191  -((corners[2].y + corners[3].y)/2 + height)
192  };
193  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Right, VuoVerticalAlignment_Top))
194  return (VuoPoint2d){
195  corners[1].x + width,
196  -corners[1].y
197  };
198  else if (a == VuoAnchor_make(VuoHorizontalAlignment_Right, VuoVerticalAlignment_Center))
199  return (VuoPoint2d){
200  (corners[1].x + corners[2].x)/2 + width,
201  -((corners[1].y + corners[2].y)/2 + height/2.)
202  };
203  else //if (a == VuoAnchor_make(VuoHorizontalAlignment_Right, VuoVerticalAlignment_Bottom))
204  return (VuoPoint2d){
205  corners[2].x + width,
206  -(corners[2].y + height)
207  };
208 }