123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /**
- * Copyright (c) 2006-2011 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
- // LOVE
- #include "ImageRasterizer.h"
- #include <common/Exception.h>
- #include <string.h>
- namespace love
- {
- namespace font
- {
- inline bool equal(const love::image::pixel& a, const love::image::pixel& b)
- {
- return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a);
- }
- ImageRasterizer::ImageRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length)
- : imageData(data), glyphs(glyphs), length(length)
- {
- imageData->retain();
- positions = new unsigned int[MAX_CHARS];
- memset(positions, 0, MAX_CHARS*4);
- widths = new unsigned int[MAX_CHARS];
- memset(widths, 0, MAX_CHARS*4);
- spacing = new unsigned int[MAX_CHARS];
- memset(spacing, 0, MAX_CHARS*4);
- load();
- }
- ImageRasterizer::~ImageRasterizer()
- {
- imageData->release();
- delete[] positions;
- delete[] widths;
- delete[] spacing;
- }
- int ImageRasterizer::getLineHeight() const
- {
- return getHeight();
- }
- GlyphData * ImageRasterizer::getGlyphData(unsigned short glyph) const
- {
- GlyphMetrics gm;
- gm.height = metrics.height;
- gm.width = widths[glyph];
- gm.advance = spacing[glyph] + widths[glyph];
- gm.bearingX = 0;
- gm.bearingY = 0;
- GlyphData * g = new GlyphData(glyph, gm, GlyphData::FORMAT_RGBA);
- if (gm.width == 0) return g;
- unsigned char * gd = (unsigned char*)g->getData();
- love::image::pixel * pixels = (love::image::pixel *)(imageData->getData());
- for (unsigned int i = 0; i < widths[glyph]*getHeight(); i++) {
- love::image::pixel p = pixels[ positions[glyph] + (i % widths[glyph]) + (imageData->getWidth() * (i / widths[glyph])) ];
- gd[i*4] = p.r;
- gd[i*4+1] = p.g;
- gd[i*4+2] = p.b;
- gd[i*4+3] = p.a;
- }
- g->pad();
- return g;
- }
- void ImageRasterizer::load()
- {
- love::image::pixel * pixels = (love::image::pixel *)(imageData->getData());
- unsigned imgw = (unsigned)imageData->getWidth();
- unsigned imgh = (unsigned)imageData->getHeight();
- unsigned imgs = imgw*imgh;
- // Set the only metric that matters
- metrics.height = imgh;
- // Reading texture data begins
- love::image::pixel spacer = pixels[0];
- unsigned int start = 0;
- unsigned int end = 0;
- for(unsigned int i = 0; i < length; ++i)
- {
- if(i >= MAX_CHARS)
- break;
- start = end;
- // Finds out where the first character starts
- while(start < imgw && equal(pixels[start], spacer))
- ++start;
- if(i > 0)
- spacing[glyphs[i - 1]] = (start > end) ? (start - end) : 0;
- end = start;
- // Find where glyph ends.
- while(end < imgw && !equal(pixels[end], spacer))
- ++end;
- if(start >= end)
- break;
- unsigned c = glyphs[i];
- positions[c] = start;
- widths[c] = (end - start);
- }
- // Replace spacer color with an empty pixel
- for(unsigned int i = 0; i < imgs; ++i)
- {
- if(equal(pixels[i], spacer))
- {
- pixels[i].r = 0;
- pixels[i].g = 0;
- pixels[i].b = 0;
- pixels[i].a = 0;
- }
- }
- }
- int ImageRasterizer::getNumGlyphs() const
- {
- return length;
- }
- } // font
- } // love
|