00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifdef _MSC_VER
00040 # pragma warning (disable: 4786)
00041 #endif
00042
00043 #include "OSGTextVectorFace.h"
00044 #include "OSGTextVectorGlyph.h"
00045 #include "OSGTextLayoutResult.h"
00046 #include "OSGTextFaceFactory.h"
00047
00048 #ifdef __sgi
00049 # include <assert.h>
00050 #else
00051 # include <cassert>
00052 #endif
00053
00054
00055 using namespace std;
00056
00057
00058 OSG_BEGIN_NAMESPACE
00059
00060
00061
00062
00063
00064
00065 TextVectorGlyph TextVectorFace::_emptyGlyph;
00066
00067
00068
00069
00070
00071
00072 TextVectorFace::~TextVectorFace()
00073 {
00074
00075 GlyphMap::iterator it;
00076 for (it = _glyphMap.begin(); it != _glyphMap.end(); ++it)
00077 {
00078 assert(it->second != 0);
00079 delete it->second;
00080 }
00081 }
00082
00083
00084
00085
00086
00087
00088 const TextGlyph &TextVectorFace::getGlyph(TextGlyph::Index glyphIndex)
00089 {
00090 return getVectorGlyph(glyphIndex);
00091 }
00092
00093
00094
00095
00096
00097
00098 const TextVectorGlyph &TextVectorFace::getVectorGlyph(TextGlyph::Index glyphIndex)
00099 {
00100 if (glyphIndex == TextGlyph::INVALID_INDEX)
00101 return _emptyGlyph;
00102
00103
00104 GlyphMap::const_iterator it = _glyphMap.find(glyphIndex);
00105 if (it != _glyphMap.end())
00106 {
00107 assert(it->second != 0);
00108 return *(it->second);
00109 }
00110
00111
00112 auto_ptr<TextVectorGlyph> glyph = createGlyph(glyphIndex);
00113
00114
00115 if (glyph.get() == 0)
00116 return _emptyGlyph;
00117
00118
00119 _glyphMap.insert(GlyphMap::value_type(glyphIndex, glyph.get()));
00120
00121
00122 return *(glyph.release());
00123 }
00124
00125
00126
00127
00128
00129
00130 void TextVectorFace::fillGeo(GeometryPtr &geoPtr, const TextLayoutResult &layoutResult,
00131 Real32 scale, Real32 depth, UInt32 level,
00132 Real32 creaseAngle)
00133 {
00134 beginEditCP(geoPtr);
00135
00136
00137
00138 GeoPositions3fPtr posPtr = GeoPositions3fPtr::dcast(geoPtr->getPositions());
00139 if (posPtr == NullFC)
00140 {
00141 posPtr = GeoPositions3f::create();
00142 geoPtr->setPositions(posPtr);
00143 }
00144 else
00145 posPtr->clear();
00146 GeoNormals3fPtr normalsPtr = GeoNormals3fPtr::dcast(geoPtr->getNormals());
00147 if (normalsPtr == NullFC)
00148 {
00149 normalsPtr = GeoNormals3f::create();
00150 geoPtr->setNormals(normalsPtr);
00151 }
00152 else
00153 normalsPtr->clear();
00154 GeoTexCoords2fPtr texPtr = GeoTexCoords2fPtr::dcast(geoPtr->getTexCoords());
00155 if (texPtr == NullFC)
00156 {
00157 texPtr = GeoTexCoords2f::create();
00158 geoPtr->setTexCoords(texPtr);
00159 }
00160 else
00161 texPtr->clear();
00162 GeoPLengthsUI32Ptr lensPtr = GeoPLengthsUI32Ptr::dcast(geoPtr->getLengths());
00163 if (lensPtr == NullFC)
00164 {
00165 lensPtr = GeoPLengthsUI32::create();
00166 geoPtr->setLengths(lensPtr);
00167 }
00168 else
00169 lensPtr->clear();
00170 GeoIndicesUI32Ptr indicesPtr = GeoIndicesUI32Ptr::dcast(geoPtr->getIndices());
00171 if (indicesPtr == NullFC)
00172 {
00173 indicesPtr = GeoIndicesUI32::create();
00174 geoPtr->setIndices(indicesPtr);
00175 }
00176 else
00177 indicesPtr->clear();
00178 GeoPTypesUI8Ptr typesPtr = GeoPTypesUI8Ptr::dcast(geoPtr->getTypes());
00179 if (typesPtr == NullFC)
00180 {
00181 typesPtr = GeoPTypesUI8::create();
00182 geoPtr->setTypes(typesPtr);
00183 }
00184 else
00185 typesPtr->clear();
00186
00187 geoPtr->setColors(NullFC);
00188 geoPtr->setSecondaryColors(NullFC);
00189 geoPtr->setTexCoords1(NullFC);
00190 geoPtr->setTexCoords2(NullFC);
00191 geoPtr->setTexCoords3(NullFC);
00192 geoPtr->getIndexMapping().clear();
00193
00194 UInt32 numGlyphs = layoutResult.getNumGlyphs();
00195 if (numGlyphs == 0)
00196 {
00197 endEditCP(geoPtr);
00198 return;
00199 }
00200
00201
00202
00203 geoPtr->getIndexMapping().push_back(Geometry::MapPosition);
00204 geoPtr->getIndexMapping().push_back(Geometry::MapNormal);
00205 geoPtr->getIndexMapping().push_back(Geometry::MapTexCoords);
00206
00207 beginEditCP(posPtr, GeoPositions3f::GeoPropDataFieldMask);
00208 beginEditCP(normalsPtr, GeoNormals3f::GeoPropDataFieldMask);
00209 beginEditCP(texPtr, GeoTexCoords2f::GeoPropDataFieldMask);
00210 beginEditCP(lensPtr, GeoPLengthsUI32::GeoPropDataFieldMask);
00211 beginEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask);
00212 beginEditCP(typesPtr, GeoPTypesUI8::GeoPropDataFieldMask);
00213
00214
00215 normalsPtr->push_back(Vec3f(0.f, 0.f, 1.f));
00216 if (depth > 0.f)
00217
00218 normalsPtr->push_back(Vec3f(0.f, 0.f, -1.f));
00219
00220 UInt32 i;
00221 for (i = 0; i < numGlyphs; ++i)
00222 {
00223 const TextVectorGlyph &glyph = getVectorGlyph(layoutResult.indices[i]);
00224 const TextVectorGlyph::PolygonOutline &outline = glyph.getLines(level);
00225 const Vec2f &pos = layoutResult.positions[i];
00226
00227
00228
00229
00230 UInt32 coordOffset = posPtr->size();
00231 UInt32 texCoordOffset = texPtr->size();
00232 Real32 coordZ = 0.5f * depth;
00233 vector<Vec2f>::const_iterator cIt;
00234 for (cIt = outline.coords.begin(); cIt != outline.coords.end(); ++cIt)
00235 {
00236 Vec2f coord = *cIt + pos;
00237 Vec2f texCoord = coord;
00238 coord *= scale;
00239 posPtr->push_back(Vec3f(coord.x(), coord.y(), coordZ));
00240 texCoord -= layoutResult.positions.front();
00241 texPtr->push_back(texCoord);
00242 }
00243
00244
00245 vector<TextVectorGlyph::PolygonOutline::TypeIndex>::const_iterator tIt;
00246 UInt32 indexBegin = 0, indexEnd;
00247 for (tIt = outline.types.begin(); tIt != outline.types.end(); ++tIt)
00248 {
00249 typesPtr->push_back(tIt->first);
00250 indexEnd = tIt->second;
00251 assert(indexEnd >= indexBegin);
00252 lensPtr->push_back(indexEnd - indexBegin);
00253 UInt32 i;
00254 for (i = indexBegin; i < indexEnd; ++i)
00255 {
00256
00257
00258 assert(i < outline.indices.size());
00259 UInt32 index = outline.indices[i];
00260 assert(coordOffset + index < posPtr->size());
00261 indicesPtr->push_back(coordOffset + index);
00262 indicesPtr->push_back(0);
00263 assert(texCoordOffset + index < texPtr->size());
00264 indicesPtr->push_back(texCoordOffset + index);
00265 }
00266 indexBegin = indexEnd;
00267 }
00268
00269
00270 if (depth > 0.f)
00271 {
00272
00273
00274
00275
00276
00277 UInt32 backCoordOffset = posPtr->size();
00278 coordZ = -0.5f * depth;
00279 for (cIt = outline.coords.begin(); cIt != outline.coords.end(); ++cIt)
00280 {
00281 Vec2f coord = *cIt + pos;
00282 coord *= scale;
00283 posPtr->push_back(Vec3f(coord.x(), coord.y(), coordZ));
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 vector<TextVectorGlyph::PolygonOutline::TypeIndex>::const_iterator tIt;
00296 UInt32 indexBegin = 0, indexEnd;
00297 for (tIt = outline.types.begin(); tIt != outline.types.end(); ++tIt)
00298 {
00299 typesPtr->push_back(tIt->first);
00300 indexEnd = tIt->second;
00301 assert(indexEnd >= indexBegin);
00302 UInt32 len = indexEnd - indexBegin;
00303 UInt32 i = indexEnd;
00304 if (tIt->first == GL_TRIANGLE_FAN)
00305 {
00306 i = indexBegin;
00307 ++indexBegin;
00308 }
00309 if ((tIt->first == GL_TRIANGLE_STRIP) && ((len & 1) == 0))
00310 {
00311 assert((indexEnd >= 2) && (indexEnd - 2 >= indexBegin));
00312 i = indexEnd - 2;
00313 ++len;
00314 }
00315 if (i != indexEnd)
00316 {
00317
00318
00319 assert(i < outline.indices.size());
00320 UInt32 index = outline.indices[i];
00321 assert(backCoordOffset + index < posPtr->size());
00322 indicesPtr->push_back(backCoordOffset + index);
00323 indicesPtr->push_back(1);
00324 assert(texCoordOffset + index < texPtr->size());
00325 indicesPtr->push_back(texCoordOffset + index);
00326 i = indexEnd;
00327 }
00328 lensPtr->push_back(len);
00329 while (true)
00330 {
00331 if (i <= indexBegin)
00332 break;
00333 --i;
00334
00335
00336
00337 assert(i < outline.indices.size());
00338 UInt32 index = outline.indices[i];
00339 assert(backCoordOffset + index < posPtr->size());
00340 indicesPtr->push_back(backCoordOffset + index);
00341 indicesPtr->push_back(1);
00342 assert(texCoordOffset + index < texPtr->size());
00343 indicesPtr->push_back(texCoordOffset + index);
00344 }
00345 indexBegin = indexEnd;
00346 }
00347
00348
00349 const TextVectorGlyph::Normals &normals = glyph.getNormals(level);
00350
00351
00352 UInt32 start = 0, end, index = 0;
00353 vector<UInt32>::const_iterator iIt;
00354 vector<TextVectorGlyph::Orientation>::const_iterator oriIt = glyph.getContourOrientations().begin();
00355 for (iIt = outline.contours.begin(); iIt != outline.contours.end(); ++iIt, ++oriIt)
00356 {
00357 assert(oriIt != glyph.getContourOrientations().end());
00358 UInt32 contourCoordOffset, contourBackCoordOffset;
00359 if (*oriIt == TextVectorGlyph::CCW)
00360 {
00361 contourCoordOffset = coordOffset;
00362 contourBackCoordOffset = backCoordOffset;
00363 }
00364 else
00365 {
00366 contourCoordOffset = backCoordOffset;
00367 contourBackCoordOffset = coordOffset;
00368 }
00369
00370 end = *iIt;
00371
00372
00373 GLenum mode = GL_QUAD_STRIP;
00374 UInt32 len = 0;
00375
00376 UInt32 coordIndex, backCoordIndex;
00377 UInt32 normalOffset, startNormalOffset = normalsPtr->size();
00378 for (index = start; index < end; ++index)
00379 {
00380 normalOffset = normalsPtr->size() - 1;
00381 assert(index < normals.size());
00382 if (normals[index].edgeAngle > creaseAngle)
00383 {
00384
00385
00386
00387 if (index > start)
00388 {
00389 if ((mode == GL_QUAD_STRIP) && (len > 2))
00390 {
00391 typesPtr->push_back(GL_QUAD_STRIP);
00392 assert(((len + 2) & 1) == 0);
00393 lensPtr->push_back(len + 2);
00394 len = 0;
00395 coordIndex = contourCoordOffset + index;
00396 backCoordIndex = contourBackCoordOffset + index;
00397 }
00398 else
00399 {
00400 mode = GL_QUADS;
00401 len += 2;
00402 coordIndex = contourBackCoordOffset + index;
00403 backCoordIndex = contourCoordOffset + index;
00404 }
00405
00406
00407 assert(backCoordIndex < posPtr->size());
00408 indicesPtr->push_back(backCoordIndex);
00409 assert(normalOffset < normalsPtr->size());
00410 indicesPtr->push_back(normalOffset);
00411 assert(texCoordOffset + index < texPtr->size());
00412 indicesPtr->push_back(texCoordOffset + index);
00413
00414 assert(coordIndex < posPtr->size());
00415 indicesPtr->push_back(coordIndex);
00416 assert(normalOffset < normalsPtr->size());
00417 indicesPtr->push_back(normalOffset);
00418 assert(texCoordOffset + index < texPtr->size());
00419 indicesPtr->push_back(texCoordOffset + index);
00420 }
00421
00422 const Vec2f &normal = normals[index].nextEdgeNormal;
00423 normalsPtr->push_back(Vec3f(normal.x(), normal.y(), 0.f));
00424 }
00425 else
00426 {
00427 if (mode == GL_QUADS)
00428 {
00429 typesPtr->push_back(GL_QUADS);
00430 mode = GL_QUAD_STRIP;
00431 assert(len >= 6);
00432 assert(((len - 2) & 3) == 0);
00433 lensPtr->push_back(len - 2);
00434 len = 2;
00435 }
00436
00437 const Vec2f &normal = normals[index].meanEdgeNormal;
00438 normalsPtr->push_back(Vec3f(normal.x(), normal.y(), 0.f));
00439 }
00440 ++normalOffset;
00441
00442
00443 assert(contourBackCoordOffset + index < posPtr->size());
00444 indicesPtr->push_back(contourBackCoordOffset + index);
00445 assert(normalOffset < normalsPtr->size());
00446 indicesPtr->push_back(normalOffset);
00447 assert(texCoordOffset + index < texPtr->size());
00448 indicesPtr->push_back(texCoordOffset + index);
00449
00450 assert(contourCoordOffset + index < posPtr->size());
00451 indicesPtr->push_back(contourCoordOffset + index);
00452 assert(normalOffset < normalsPtr->size());
00453 indicesPtr->push_back(normalOffset);
00454 assert(texCoordOffset + index < texPtr->size());
00455 indicesPtr->push_back(texCoordOffset + index);
00456
00457 len += 2;
00458 }
00459
00460
00461 if (normals[start].edgeAngle <= creaseAngle)
00462 normalOffset = startNormalOffset;
00463 if (mode == GL_QUAD_STRIP)
00464 {
00465 coordIndex = contourCoordOffset + start;
00466 backCoordIndex = contourBackCoordOffset + start;
00467 }
00468 else
00469 {
00470 coordIndex = contourBackCoordOffset + start;
00471 backCoordIndex = contourCoordOffset + start;
00472 }
00473
00474
00475 assert(backCoordIndex < posPtr->size());
00476 indicesPtr->push_back(backCoordIndex);
00477 assert(normalOffset < normalsPtr->size());
00478 indicesPtr->push_back(normalOffset);
00479 assert(texCoordOffset + start < texPtr->size());
00480 indicesPtr->push_back(texCoordOffset + start);
00481
00482 assert(coordIndex < posPtr->size());
00483 indicesPtr->push_back(coordIndex);
00484 assert(normalOffset < normalsPtr->size());
00485 indicesPtr->push_back(normalOffset);
00486 assert(texCoordOffset + start < texPtr->size());
00487 indicesPtr->push_back(texCoordOffset + start);
00488
00489 len += 2;
00490
00491
00492 typesPtr->push_back(mode);
00493 assert((mode != GL_QUADS) || ((len & 3) == 0));
00494 assert((mode != GL_QUAD_STRIP) || ((len & 1) == 0));
00495 lensPtr->push_back(len);
00496
00497 start = end;
00498 }
00499 }
00500 }
00501
00502 endEditCP(typesPtr, GeoPTypesUI8::GeoPropDataFieldMask);
00503 endEditCP(indicesPtr, GeoIndicesUI32::GeoPropDataFieldMask);
00504 endEditCP(lensPtr, GeoPLengthsUI32::GeoPropDataFieldMask);
00505 endEditCP(texPtr, GeoTexCoords2f::GeoPropDataFieldMask);
00506 endEditCP(normalsPtr, GeoNormals3f::GeoPropDataFieldMask);
00507 endEditCP(posPtr, GeoPositions3f::GeoPropDataFieldMask);
00508
00509 endEditCP(geoPtr);
00510 }
00511
00512
00513
00514
00515
00516
00517 GeometryPtr TextVectorFace::makeGeo(const TextLayoutResult &layoutResult, Real32 scale,
00518 Real32 depth, UInt32 level, Real32 creaseAngle)
00519 {
00520 GeometryPtr geo = Geometry::create();
00521 fillGeo(geo, layoutResult, scale, depth, level, creaseAngle);
00522 return geo;
00523 }
00524
00525
00526
00527
00528
00529
00530 NodePtr TextVectorFace::makeNode(const TextLayoutResult &layoutResult, Real32 scale,
00531 Real32 depth, UInt32 level, Real32 creaseAngle)
00532 {
00533 GeometryPtr geo = makeGeo(layoutResult, scale, depth, level, creaseAngle);
00534 NodePtr node = Node::create();
00535 beginEditCP(node, Node::CoreFieldMask);
00536 node->setCore(geo);
00537 endEditCP(node, Node::CoreFieldMask);
00538 return node;
00539 }
00540
00541
00542
00543
00544
00545
00546 TextVectorFace *TextVectorFace::create(const std::string &family, Style style)
00547 { return TextFaceFactory::the().createVectorFace(family, style); }
00548
00549
00550 OSG_END_NAMESPACE
00551
00552
00553
00554
00555
00556 #ifdef OSG_SGI_CC
00557 #pragma set woff 1174
00558 #endif
00559
00560 #ifdef OSG_LINUX_ICC
00561 #pragma warning( disable : 177 )
00562 #endif
00563
00564 namespace
00565 {
00566 static OSG::Char8 cvsid_cpp[] = "@(#)$Id: OSGTextVectorFace.cpp,v 1.2 2005/04/12 14:43:41 jbehr Exp $";
00567 static OSG::Char8 cvsid_hpp[] = OSGTEXTVECTORFACE_HEADER_CVSID;
00568 static OSG::Char8 cvsid_inl[] = OSGTEXTVECTORFACE_INLINE_CVSID;
00569 }
00570
00571 #ifdef __sgi
00572 #pragma reset woff 1174
00573 #endif