Esempio n. 1
0
osgText::Glyph* ScaledAltFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode) {
	{
		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_glyphMapMutex);
		FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes);
		if (itr != _sizeGlyphMap.end()) {
			GlyphMap& glyphmap = itr->second;
			GlyphMap::iterator gitr = glyphmap.find(charcode);
			if (gitr!=glyphmap.end()) return gitr->second.get();
		}
	}
	if (_implementation.valid()) {
		if (charcode >= 128) {
			unsigned int normal_code = charcode % 128;
			// Reload a scaled version of the glyph
			osgText::Glyph *normal_glyph = getGlyph(fontRes, normal_code);

			const osgText::FontResolution new_fontRes(fontRes.first * m_Scale, fontRes.second * m_Scale);
			osgText::Glyph *scaled_glyph = _implementation->getGlyph(new_fontRes, normal_code);
			if (m_VCenter) {
				osg::Vec2 hbearing = scaled_glyph->getHorizontalBearing();
				hbearing.y() += 0.5f * (normal_glyph->t() - scaled_glyph->t());
				scaled_glyph->setHorizontalBearing(hbearing);
			}
			addGlyph (fontRes, charcode, scaled_glyph);
			return scaled_glyph;
		} else {
			osgText::Glyph* g = _implementation->getGlyph(fontRes, charcode);
			addGlyph (fontRes, charcode, g);
			return g;
		}
	}
	return 0;
}
Esempio n. 2
0
void ULLineEditor::pushFirstGlyphAtLastOfPrevLine()
{
	PageBuffer *PB = PageBuffer::getInstance();

	if ( PB->maxId() == 0 )
		return;

	uint prevlineId;
	uint curId;
	if ( reedit )
	{
		prevlineId = reedit_id - 1;
		curId = reedit_id;
	}
	else
	{
		prevlineId = PB->maxId();
		curId = prevlineId + 1;
	}

	ULGlyphItem *it=takeFirst();
	qDebug() << it->key;
	slotEditGroup(m_mainScene->groupById(prevlineId));
	addGlyph(it);
	slotEditGroup(m_mainScene->groupById(curId));

}
Esempio n. 3
0
void ULLineEditor::insertAtFirstLastGlyphFromPrevLine()
{
	PageBuffer *PB = PageBuffer::getInstance();

	if ( PB->maxId() == 0 ) //The line we are editing is the first one
		return;

	uint prevlineId;
	int curLineId;
	if ( reedit )
	{
		curLineId = reedit_id;
		prevlineId = reedit_id - 1;
	}
	else
	{
		prevlineId = PB->maxId();
		curLineId = prevlineId + 1;
	}

	slotEditGroup(m_mainScene->groupById(prevlineId));
	ULGlyphItem *it= takeLast();
	slotEditGroup(m_mainScene->groupById(curLineId));
	addGlyph(it, false);


}
Esempio n. 4
0
int32_t ewol::resource::TexturedFont::getIndex(char32_t _charcode, const enum ewol::font::mode _displayMode) {
	std::unique_lock<std::recursive_mutex> lock(m_mutex);
	if (_charcode < 0x20) {
		return 0;
	} else if (_charcode < 0x80) {
		return _charcode - 0x1F;
	} else {
		for (size_t iii=0x80-0x20; iii < m_listElement[_displayMode].size(); iii++) {
			//EWOL_DEBUG("search : '" << charcode << "' =?= '" << (m_listElement[displayMode])[iii].m_UVal << "'");
			if (_charcode == (m_listElement[_displayMode])[iii].m_UVal) {
				//EWOL_DEBUG("search : '" << charcode << "'");
				if ((m_listElement[_displayMode])[iii].exist()) {
					//EWOL_DEBUG("return " << iii);
					return iii;
				} else {
					return 0;
				}
			}
		}
	}
	if (addGlyph(_charcode) == true) {
		// TODO : This does not work due to the fact that the update of open GL is not done in the context main cycle !!!
		ewol::getContext().forceRedrawAll();
	}
	return 0;
}
Esempio n. 5
0
void ActivityDiagram::paste()
{
	//map<sample, clone>
	map<Glyph*, Glyph*> glyphMap;
	// 新增
	for (unsigned int i = 0; i < _copyGlyphs.size(); i++)
	{
		int id = _idCount;
		_idCount++;
		Glyph *glyphClone = addGlyph(id, _copyGlyphs[i]->getType(), _copyGlyphs[i]->getText());
		glyphClone->setWidth(_copyGlyphs[i]->getWidth());
		glyphClone->setHeight(_copyGlyphs[i]->getHeight());
		if (glyphClone->getType() == EDGE)
		{
			glyphClone->setWidth(glyphClone->getWidth() + DELTA_X);
			glyphClone->setHeight(glyphClone->getHeight() + DELTA_Y);
		}
		glyphClone->setX(_copyGlyphs[i]->getX() + DELTA_X);
		glyphClone->setY(_copyGlyphs[i]->getY() + DELTA_Y);
		glyphMap.insert(pair<Glyph*, Glyph*>(_copyGlyphs[i], glyphClone));
	}
	connectCopyGlyph(_copyGlyphs, glyphMap);

	notify();
}
    bool loadGlyphIfPossible (const juce_wchar character)
    {
        if (faceWrapper != nullptr)
        {
            FT_Face face = faceWrapper->face;
            const unsigned int glyphIndex = FT_Get_Char_Index (face, character);

            if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_HINTING) == 0
                  && face->glyph->format == ft_glyph_format_outline)
            {
                const float scale = 1.0f / (float) (face->ascender - face->descender);
                Path destShape;

                if (getGlyphShape (destShape, face->glyph->outline, scale))
                {
                    addGlyph (character, destShape, face->glyph->metrics.horiAdvance * scale);

                    if ((face->face_flags & FT_FACE_FLAG_KERNING) != 0)
                        addKerning (face, character, glyphIndex);

                    return true;
                }
            }
        }

        return false;
    }
Esempio n. 7
0
const Font::Glyph* Font::findGlyph(uint32 codepoint)
{
  auto glyph = std::find(m_glyphs.begin(), m_glyphs.end(), codepoint);
  if (glyph == m_glyphs.end())
    return addGlyph(codepoint);

  return &(*glyph);
}
LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const
{
	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
	if (iter != mCharGlyphInfoMap.end())
	{
		return iter->second;
	}
	else
	{
		// this glyph doesn't yet exist, so render it and return the result
		return addGlyph(wch);
	}
}
	void ResourceManualFont::addRange(VectorPairCodeCoord& _info, size_t _first, size_t _last, int _width, int _height, float _aspect)
	{
		RangeInfo range = RangeInfo(_info[_first].code, _info[_last].code);

		for (size_t pos = _first; pos <= _last; ++pos)
		{
			GlyphInfo* info = range.getInfo(_info[pos].code);
			const IntCoord& coord = _info[pos].coord;
			addGlyph(info, _info[pos].code, coord.left, coord.top, coord.right(), coord.bottom(), _width, _height, _aspect);

			if (_info[pos].code == FontCodeType::Space)
				mSpaceGlyphInfo = *info;
		}

		mVectorRangeInfo.push_back(range);
	}
Esempio n. 10
0
void LLFont::resetBitmapCache()
{
	// Iterate through glyphs and clear the mIsRendered flag
	for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
		 iter != mCharGlyphInfoMap.end(); ++iter)
	{
		iter->second->mIsRendered = FALSE;
		//FIXME: this is only strictly necessary when resetting the entire font, 
		//not just flushing the bitmap
		iter->second->mMetricsValid = FALSE;
	}
	mFontBitmapCachep->reset();

	// Add the empty glyph`5
	addGlyph(0, 0);
}
Esempio n. 11
0
    void FontReader::read(std::istream *source, Font *target)
    {
        enum {
            keyState,
            glyphState
        } state = keyState;
        std::string line;
        while (std::getline(*source, line)) {
            strip(&line);
            switch (state) {
                case keyState:
                    if (!line.empty()) {
                        keyLine_ = line;
                        state = glyphState;
                        glyphWidth_ = 0;
                        glyphHeight_ = 0;
                    }
                    break;

                case glyphState:
                    if (line.empty()) {
                        if (glyphHeight_) {
                            addGlyph(target);
                            state = keyState;
                        }
                    } else {
                        if (glyphWidth_ == 0) {
                            glyphWidth_ = line.size();
                        } else {
                            if (line.size() != glyphWidth_) {
                                std::stringstream message;
                                message << "Glyph width mismatch: " << line;
                                throw Error(message.str());
                            }
                        }
                        if (glyphHeight_ == glyphLines_.size()) {
                            glyphLines_.resize(glyphLines_.size() + 1);
                        }
                        glyphLines_[glyphHeight_] = line;
                        ++glyphHeight_;
                    }
                    break;
            }
        }
    }
Esempio n. 12
0
void ULLineEditor::insertAtLastFirstGlyphOfNextLine()
{
	PageBuffer *PB = PageBuffer::getInstance();

	if ( !reedit ) //Last line is current
		return;
	if(reedit_id == PB->maxId())//We are the last
		return;
	
	uint nextlineId = reedit_id + 1;
	uint curId = reedit_id;
	slotEditGroup(m_mainScene->groupById(nextlineId));
	ULGlyphItem *it = takeFirst();
	slotEditGroup(m_mainScene->groupById(curId));
	addGlyph(it);
	
	
}
Esempio n. 13
0
void ULLineEditor::pushLastGlyphAtFirstOfNextLine()
{
	PageBuffer *PB = PageBuffer::getInstance();

	if ( !reedit ) //Last line is current
		return;
	if(reedit_id == PB->maxId())//We are the last
		return;

	uint nextlineId = reedit_id + 1;
	uint curId = reedit_id;

	ULGlyphItem *LaGlFrLi = takeLast();
	slotEditGroup(m_mainScene->groupById(nextlineId));
	addGlyph(LaGlFrLi, false);
	slotEditGroup(m_mainScene->groupById(curId));
	
	
}
Esempio n. 14
0
    ImageFont::ImageFont(const std::string& filename, unsigned char glyphsFrom,
                         unsigned char glyphsTo)
    {
        mFilename = filename;
        mImage = Image::load(filename, false);

        Color separator = mImage->getPixel(0, 0);

        int i = 0;
        for (i=0; separator == mImage->getPixel(i, 0)
                 && i < mImage->getWidth(); ++i)
        {
        }

        if (i >= mImage->getWidth())
        {
            throw GCN_EXCEPTION("Corrupt image.");
        }

        int j = 0;
        for (j = 0; j < mImage->getHeight(); ++j)
        {
            if (separator == mImage->getPixel(i, j))
            {
                break;
            }
        }

        mHeight = j;
        int x = 0, y = 0;

        for (i=glyphsFrom; i<glyphsTo+1; i++)
        {
            addGlyph(i, x, y, separator);
        }

        int w = mImage->getWidth();
        int h = mImage->getHeight();
        mImage->convertToDisplayFormat();

        mRowSpacing = 0;
        mGlyphSpacing = 0;
    }
Esempio n. 15
0
void CPetRooms::load(SimpleFile *file, int param) {
	if (!param) {
		int count = file->readNumber();

		for (int idx = 0; idx < count; ++idx) {
			CPetRoomsGlyph *glyph = addGlyph(file->readNumber(), false);
			glyph->setMode((RoomGlyphMode)file->readNumber());
		}

		_glyphItem.setMode((RoomGlyphMode)file->readNumber());
		file->readNumber();
		_floorNum = file->readNumber();
		_elevatorNum = file->readNumber();
		_roomNum = file->readNumber();
		_field1CC = file->readNumber();
		_wellEntry = file->readNumber();
		_field1D4 = file->readNumber();
	}
}
	void ResourceManualFont::deserialization(xml::ElementPtr _node, Version _version)
	{
		Base::deserialization(_node, _version);

		xml::ElementEnumerator node = _node->getElementEnumerator();
		while (node.next())
		{
			if (node->getName() == "Property")
			{
				const std::string& key = node->findAttribute("key");
				const std::string& value = node->findAttribute("value");
				if (key == "Source") mSource = value;
				else if (key == "DefaultHeight") mDefaultHeight = utility::parseInt(value);
			}
			else if (node->getName() == "Codes")
			{
				xml::ElementEnumerator range = node->getElementEnumerator();
				while (range.next("Code"))
				{
					std::string range_value;
					std::vector<std::string> parse_range;
					// описане глифов
					if (range->findAttribute("index", range_value))
					{
						Char id = 0;
						if (range_value == "cursor")
							id = FontCodeType::Cursor;
						else if (range_value == "selected")
							id = FontCodeType::Selected;
						else if (range_value == "selected_back")
							id = FontCodeType::SelectedBack;
						else
							id = utility::parseUInt(range_value);

						addGlyph(id, utility::parseValue<IntCoord>(range->findAttribute("coord")));
					}
				}
			}
		}

		// инициализируем
		initialise();
	}
Esempio n. 17
0
CPetRoomsGlyph *CPetRooms::addRoom(uint roomFlags, bool highlight_) {
	// Ensure that we don't add room if the room is already present
	if (_glyphs.hasFlags(roomFlags))
		return nullptr;

	if (_glyphs.size() >= 32) {
		// Too many room glyphs present. Scan for and remove the first
		// glyph that isn't for an assigned bedroom
		for (CPetRoomsGlyphs::iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) {
			CPetRoomsGlyph *glyph = dynamic_cast<CPetRoomsGlyph *>(*i);
			if (!glyph->isAssigned()) {
				_glyphs.erase(i);
				break;
			}
		}
	}

	// Add the glyph
	return addGlyph(roomFlags, highlight_);
}
Esempio n. 18
0
BOOL LLFont::addChar(const llwchar wch) const
{
	if (mFTFace == NULL)
		return FALSE;

	llassert(!mIsFallback);
	//lldebugs << "Adding new glyph for " << wch << " to font" << llendl;

	FT_UInt glyph_index;

	// Initialize char to glyph map
	glyph_index = FT_Get_Char_Index(mFTFace, wch);
	if (glyph_index == 0)
	{
		// Try looking it up in the backup Unicode font
		if (mFallbackFontp)
		{
			//llinfos << "Trying to add glyph from fallback font!" << llendl
			LLFontList::iterator iter;
			for(iter = mFallbackFontp->begin(); iter != mFallbackFontp->end(); iter++)
			{
				glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
				if (glyph_index)
				{
					addGlyphFromFont(*iter, wch, glyph_index);
					return TRUE;
				}
			}
		}
	}
	
	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
	if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
	{
		BOOL result = addGlyph(wch, glyph_index);
		return result;
	}
	return FALSE;
}
Esempio n. 19
0
CPetRoomsGlyph *CPetRooms::addRoom(uint roomFlags, bool highlight_) {
	// Ensure that we don't add room if the room is already present
	if (_glyphs.hasFlags(roomFlags))
		return nullptr;

	if (_glyphs.size() >= 32)
		// Too many rooms already
		return nullptr;

	// Do a preliminary scan of the glyph list for any glyph that is
	// no longer valid, and thus can be removed
	for (CPetRoomsGlyphs::iterator i = _glyphs.begin(); i != _glyphs.end(); ++i) {
		CPetRoomsGlyph *glyph = dynamic_cast<CPetRoomsGlyph *>(*i);
		if (!glyph->isAssigned()) {
			_glyphs.erase(i);
			break;
		}
	}

	// Add the glyph
	return addGlyph(roomFlags, highlight_);
}
Esempio n. 20
0
    bool loadGlyphIfPossible (juce_wchar character)
    {
        HDC dc = FontDCHolder::getInstance()->loadFont (name, isBold, isItalic, 0);

        GLYPHMETRICS gm;

        // if this is the fallback font, skip checking for the glyph's existence. This is because
        // with fonts like Tahoma, GetGlyphIndices can say that a glyph doesn't exist, but it still
        // gets correctly created later on.
        if (! isFallbackFont)
        {
            const WCHAR charToTest[] = { (WCHAR) character, 0 };
            WORD index = 0;

            if (GetGlyphIndices (dc, charToTest, 1, &index, GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR
                 && index == 0xffff)
            {
                return false;
            }
        }

        Path glyphPath;

        TEXTMETRIC tm;
        if (! GetTextMetrics (dc, &tm))
        {
            addGlyph (character, glyphPath, 0);
            return true;
        }

        const float height = (float) tm.tmHeight;
        static const MAT2 identityMatrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };

        const int bufSize = GetGlyphOutline (dc, character, GGO_NATIVE,
                                             &gm, 0, 0, &identityMatrix);

        if (bufSize > 0)
        {
            HeapBlock<char> data (bufSize);

            GetGlyphOutline (dc, character, GGO_NATIVE, &gm,
                             bufSize, data, &identityMatrix);

            const TTPOLYGONHEADER* pheader = reinterpret_cast<TTPOLYGONHEADER*> (data.getData());

            const float scaleX = 1.0f / height;
            const float scaleY = -1.0f / height;

            while ((char*) pheader < data + bufSize)
            {
                float x = scaleX * pheader->pfxStart.x.value;
                float y = scaleY * pheader->pfxStart.y.value;

                glyphPath.startNewSubPath (x, y);

                const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
                const char* const curveEnd = ((const char*) pheader) + pheader->cb;

                while ((const char*) curve < curveEnd)
                {
                    if (curve->wType == TT_PRIM_LINE)
                    {
                        for (int i = 0; i < curve->cpfx; ++i)
                        {
                            x = scaleX * curve->apfx[i].x.value;
                            y = scaleY * curve->apfx[i].y.value;

                            glyphPath.lineTo (x, y);
                        }
                    }
                    else if (curve->wType == TT_PRIM_QSPLINE)
                    {
                        for (int i = 0; i < curve->cpfx - 1; ++i)
                        {
                            const float x2 = scaleX * curve->apfx[i].x.value;
                            const float y2 = scaleY * curve->apfx[i].y.value;
                            float x3, y3;

                            if (i < curve->cpfx - 2)
                            {
                                x3 = 0.5f * (x2 + scaleX * curve->apfx[i + 1].x.value);
                                y3 = 0.5f * (y2 + scaleY * curve->apfx[i + 1].y.value);
                            }
                            else
                            {
                                x3 = scaleX * curve->apfx[i + 1].x.value;
                                y3 = scaleY * curve->apfx[i + 1].y.value;
                            }

                            glyphPath.quadraticTo (x2, y2, x3, y3);

                            x = x3;
                            y = y3;
                        }
                    }

                    curve = (const TTPOLYCURVE*) &(curve->apfx [curve->cpfx]);
                }

                pheader = (const TTPOLYGONHEADER*) curve;

                glyphPath.closeSubPath();
            }
        }

        addGlyph (character, glyphPath, gm.gmCellIncX / height);

        int numKPs;
        const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);

        for (int i = 0; i < numKPs; ++i)
        {
            if (kps[i].wFirst == character)
                addKerningPair (kps[i].wFirst, kps[i].wSecond,
                                kps[i].iKernAmount / height);
        }

        return true;
    }
Esempio n. 21
0
void ewol::resource::DistanceFieldFont::init(const std::string& _fontName) {
	std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
	ewol::resource::Texture::init(_fontName);
	std::string localName = _fontName;
	std::vector<std::string> folderList;
	if (true == ewol::getContext().getFontDefault().getUseExternal()) {
		#if defined(__TARGET_OS__Android)
			folderList.push_back("ROOT:system/fonts");
		#elif defined(__TARGET_OS__Linux)
			folderList.push_back("ROOT:usr/share/fonts/truetype");
		#endif
	}
	std::string applicationBaseFont = ewol::getContext().getFontDefault().getFolder();
	std::vector<std::string> applicationBaseFontList = etk::FSNodeExplodeMultiplePath(applicationBaseFont);
	for (auto &it : applicationBaseFontList) {
		folderList.push_back(it);
	}
	for (size_t folderID = 0; folderID < folderList.size() ; folderID++) {
		etk::FSNode myFolder(folderList[folderID]);
		// find the real Font name :
		std::vector<std::string> output;
		myFolder.folderGetRecursiveFiles(output);
		std::vector<std::string> split = etk::split(localName, ';');
		EWOL_INFO("try to find font named : " << split << " in: " << myFolder);
		//EWOL_CRITICAL("parse string : " << split);
		bool hasFindAFont = false;
		for (size_t jjj=0; jjj<split.size(); jjj++) {
			EWOL_INFO("    try with : '" << split[jjj] << "'");
			for (size_t iii=0; iii<output.size(); iii++) {
				//EWOL_DEBUG(" file : " << output[iii]);
				if(    true == etk::end_with(output[iii], split[jjj]+"-"+"regular"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"-"+"r"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"regular"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"r"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+".ttf", false)) {
					EWOL_INFO(" find Font [Regular]     : " << output[iii]);
					m_fileName = output[iii];
					hasFindAFont=true;
					break;
				}
			}
			if (hasFindAFont == true) {
				EWOL_INFO("    find this font : '" << split[jjj] << "'");
				break;
			} else if (jjj == split.size()-1) {
				EWOL_ERROR("Find NO font in the LIST ... " << split);
			}
		}
		if (hasFindAFont == true) {
			EWOL_INFO("    find this font : '" << folderList[folderID] << "'");
			break;
		} else if (folderID == folderList.size()-1) {
			EWOL_ERROR("Find NO font in the LIST ... " << folderList);
		}
	}
	
	if (m_fileName.size() == 0) {
		EWOL_ERROR("can not load FONT name : '" << m_fileName << "'" );
		m_font = nullptr;
		return;
	}
	EWOL_INFO("Load FONT name : '" << m_fileName << "'");
	m_font = ewol::resource::FontFreeType::create(m_fileName);
	if (m_font == nullptr) {
		EWOL_ERROR("Pb Loading FONT name : '" << m_fileName << "'" );
	}
	
	// set the bassic charset:
	m_listElement.clear();
	if (m_font == nullptr) {
		return;
	}
	if (importFromFile() == true) {
		EWOL_INFO("GET distance field from previous file");
		flush();
		return;
	}
	
	m_sizeRatio = ((float)SIZE_GENERATION) / ((float)m_font->getHeight(SIZE_GENERATION));
	// TODO : basic font use 512 is better ...  == > maybe estimate it with the dpi ???
	setImageSize(ivec2(256,32));
	// now we can acces directly on the image
	m_data.clear(etk::Color<>(0x00000000));
	
	// add error glyph
	addGlyph(0);
	// by default we set only the first AINSI char availlable
	for (int32_t iii=0x20; iii<0x7F; iii++) {
		addGlyph(iii);
	}
	flush();
	//exportOnFile();
}
Esempio n. 22
0
IPXdevLFont XdevLFontSystemRAI::createFontFromTexture(IPXdevLFile& file, IPXdevLTexture texture) {
    assert(m_rai && " XdevLFontImpl::createFontFromTexture: XdevLFontSystem not initialized.");

    auto font = std::shared_ptr<XdevLFontRAI>(new XdevLFontRAI());

    IPXdevLTexture tx = texture;
    font->addFontTexture(texture);

    tx->lock();
    tx->setTextureFilter(XDEVL_TEXTURE_MIN_FILTER, XDEVL_NEAREST);
    tx->setTextureFilter(XDEVL_TEXTURE_MAG_FILTER, XDEVL_NEAREST);
    tx->setTextureWrap(XDEVL_TEXTURE_WRAP_S, XDEVL_CLAMP_TO_EDGE);
    tx->setTextureWrap(XDEVL_TEXTURE_WRAP_T, XDEVL_CLAMP_TO_EDGE);
    tx->unlock();


    // One unit on the screen for x,y [-1 , 1]
    font->setUnitX(2.0f/(xdl_float)screenWidth);
    font->setUnitY(2.0f/(xdl_float)screenHeight);

    xdl_uint numberOfTextures = 1;
    xdl_uint fontSize = 0;


    XdevLString tmp;
    file->readString(tmp);
    file->readString(tmp);

    file->readString(tmp);
    std::stringstream ss(tmp.toString());
    ss >> numberOfTextures;
    ss.str("");
    ss.clear();

    // Get font size.
    file->readString(tmp);
    ss << tmp;
    ss >> fontSize;

    font->setFontSize(fontSize);

    xdl_float numCols 	= (xdl_float)tx->getWidth()/(xdl_float)fontSize;

    // TODO Using maps to handle id of the glyphs? At the moment it is just a hack.
    while(file->tell() != file->length()) {

        XdevLGlyphMetric gp;
        readLine(file, gp);

        //
        // TODO This part to find the position of the glyph in the texture is some sort of hack.
        // Make it so that all of the information is the the fontInfo.txt file.
        //
        xdl_uint idx = gp.character_code - 32;

        xdl_float pos_x = idx % (xdl_int)numCols;
        xdl_float pos_y = idx / (xdl_int)numCols;

        xdl_float ds = 1.0/(xdl_float)tx->getWidth()*gp.width;
        xdl_float dt = 1.0/(xdl_float)tx->getWidth()*gp.height;

        xdl_float s = 1.0/numCols*pos_x ;
        xdl_float t = 1.0 - 1.0/numCols*pos_y - (1.0/(xdl_float)tx->getHeight())*((fontSize - gp.height - gp.top));

        //
        // Add an offset of x,y pixel offset to the s,t coordinates.
        //
        xdl_float offset_x = 0.0/(xdl_float)tx->getWidth();
        xdl_float offset_y = 0.0/(xdl_float)tx->getHeight();


        gp.vertices[0].x = gp.brearing_x;
        gp.vertices[0].y = (gp.height - gp.brearing_y);
        gp.vertices[0].s = s - offset_x;
        gp.vertices[0].t = t - dt - offset_y;

        gp.vertices[1].x = gp.brearing_x;
        gp.vertices[1].y = gp.brearing_y;
        gp.vertices[1].s = s - offset_x;
        gp.vertices[1].t = t + offset_y;

        gp.vertices[2].x = gp.brearing_x + gp.width;
        gp.vertices[2].y = gp.brearing_y;
        gp.vertices[2].s = s + ds + offset_x;
        gp.vertices[2].t = t + offset_y;

        gp.vertices[3].x = gp.brearing_x + gp.width;
        gp.vertices[3].y = (gp.height - gp.brearing_y);
        gp.vertices[3].s = s + ds + offset_x;
        gp.vertices[3].t = t - dt - offset_y;

        //
        // Find maximum value for the new line.
        //
        font->setNewLineSize(std::max(font->getNewLineSize(), gp.height));

        font->addGlyph(gp);

    }
    return font;

}
Esempio n. 23
0
osgText::Glyph* ReverseAltFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode) {
	{
		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_glyphMapMutex);
		FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes);
		if (itr != _sizeGlyphMap.end()) {
			GlyphMap& glyphmap = itr->second;
			GlyphMap::iterator gitr = glyphmap.find(charcode);
			if (gitr!=glyphmap.end()) return gitr->second.get();
		}
	}
	if (_implementation.valid()) {
		if (charcode >= 128) {
			// use '0' as the reference glyph for sizing and centering the new glyph.  'M' would
			// probably be a better choice, but i haven't made that glyph yet in my test font ;-)
			osgText::Glyph *reference = getGlyph(fontRes, '0');
			osgText::Glyph *normal = getGlyph(fontRes, charcode % 128);
			osgText::Glyph *reverse = new osgText::Glyph(this, 0);
			int reference_width = reference->s();
			int reference_height = reference->t();
			int source_width = normal->s();
			int source_height = normal->t();

			// the new glyph should fit the full character cell.  we expand the horizontal dimensions slightly
			// to compensate for texture blending at the edges of the glyph that might otherwise cause a gap
			// between adjacent reverse video characters.
			int cell_height = static_cast<int>(reference->getVerticalAdvance() + 0.5);
			int cell_width = static_cast<int>(reference->getHorizontalAdvance() + 0.5) + 2 * getGlyphImageMargin();

			// sanity checking
			cell_width = std::max(cell_width, source_width);
			cell_height = std::max(cell_height, source_height);
			unsigned int cell_data_size = cell_height * cell_width;
			unsigned int data_size = normal->getImageSizeInBytes();
			unsigned int bits_per_pixel = normal->getPixelSizeInBits();
			assert(bits_per_pixel == 8);
			assert(normal->r() == 1);
			assert(cell_height >= source_height);
			assert(cell_width >= source_width);
			assert(data_size = source_width * source_height);

			// create and initialize the image array for the new glyph
			unsigned char const *image = normal->data();
			unsigned char *data = new unsigned char[cell_data_size];
			for (unsigned char *init = data; init < data + cell_data_size; ) {
				*init++ = 0xff;  // opaque
			}

			// the new glyph cell is position based on the reference character.  this ensures that
			// the edges line up correctly for different characters.  the actual glyph needs to be
			// offset relative to the reference character based on the character metrics.  this
			// offset is hard-coded into the new image, since the metrics for the new glyph will
			// be based entirely on the reference glyph.
			osg::Vec2 glyph_offset = reference->getHorizontalBearing() - normal->getHorizontalBearing();
			unsigned int offset_top = static_cast<unsigned int>(std::max(0.0f, (cell_height - reference_height) / 2 - glyph_offset.y()));
			unsigned int offset_left = static_cast<unsigned int>(std::max(0.0f, (cell_width - reference_width) / 2 - glyph_offset.x()));
			unsigned char const *source = image;
			unsigned char *copy = data + offset_top * cell_width + offset_left;
			for (int j = 0; j < source_height; j++) {
				for (int i = 0; i < source_width; i++) {
					*copy++ = *source++ ^ 0xff;
				}
				copy += cell_width - source_width;
			}
			reverse->setImage(cell_width, cell_height, 1, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1);

			// finally set the metrics such that the reference glyph would be centered in the
			// cell.  offsets for this specific glyph have already been accounted for when
			// generating the new glyph image.
			osg::Vec2 horizontal_bearing = reference->getHorizontalBearing();
			horizontal_bearing.x() -= (cell_width - reference_width) / 2;
			horizontal_bearing.y() -= (cell_height - reference_height) / 2;
			reverse->setHorizontalBearing(horizontal_bearing);

			// force uniform spacing, even if the font has variable width characters
			reverse->setHorizontalAdvance(reference->getHorizontalAdvance());

			// no adjustments to the vertical metrics for now; ReverseAltFont is intended for
			// horizontal text only.
			reverse->setVerticalBearing(reference->getVerticalBearing());
			reverse->setVerticalAdvance(reference->getVerticalAdvance());

			// finally add the new glyph so we don't repeat all this work!
			addGlyph(fontRes, charcode, reverse);
			return reverse;
		} else {
			osgText::Glyph *g = _implementation->getGlyph(fontRes,charcode);
			addGlyph (fontRes, charcode, g);
			return g;
		}
	}
	return 0;
}
 std::pair<FontData*, FontAtlas*> FontManager::fetchFontDataAndAtlas(InputSourceRef source)
 {
     auto in = source->loadDataSource()->createStream(); // CAN THROW
     
     string version;
     in->readFixedString(&version, 10);
     
     if (version != "XFONT.003")
     {
         throw runtime_error("Font: WRONG FORMAT");
     }
     
     // ---
     
     int glyphCount;
     in->readLittle(&glyphCount);
     
     auto data = new FontData(glyphCount);
     
     in->readLittle(&data->baseSize);
     in->readLittle(&data->height);
     in->readLittle(&data->ascent);
     in->readLittle(&data->descent);
     in->readLittle(&data->spaceAdvance);
     in->readLittle(&data->strikethroughFactor);
     in->readLittle(&data->underlineOffset);
     in->readLittle(&data->lineThickness);
     
     int atlasWidth;
     int atlasHeight;
     int atlasPadding;
     int unitMargin;
     int unitPadding;
     
     in->readLittle(&atlasWidth);
     in->readLittle(&atlasHeight);
     in->readLittle(&atlasPadding);
     in->readLittle(&unitMargin);
     in->readLittle(&unitPadding);
     
     auto atlas = new FontAtlas(atlasWidth, atlasHeight);
     
     for (int i = 0; i < glyphCount; i++)
     {
         int glyphChar;
         int glyphWidth;
         int glyphHeight;
         int glyphLeftExtent;
         int glyphTopExtent;
         int glyphAtlasX;
         int glyphAtlasY;
         
         in->readLittle(&glyphChar);
         data->glyphs[(wchar_t)glyphChar] = i;
         
         in->readLittle(&data->advance[i]);
         in->readLittle(&glyphWidth);
         in->readLittle(&glyphHeight);
         in->readLittle(&glyphLeftExtent);
         in->readLittle(&glyphTopExtent);
         in->readLittle(&glyphAtlasX);
         in->readLittle(&glyphAtlasY);
         
         auto glyphData = new unsigned char[glyphWidth * glyphHeight];
         in->readData(glyphData, glyphWidth * glyphHeight);
         atlas->addGlyph(glyphData, glyphAtlasX + atlasPadding + unitMargin, glyphAtlasY + atlasPadding + unitMargin, glyphWidth, glyphHeight);
         delete[] glyphData;
         
         data->w[i] = glyphWidth + unitPadding * 2;
         data->h[i] = glyphHeight + unitPadding * 2;
         data->le[i] = glyphLeftExtent - unitPadding;
         data->te[i] = glyphTopExtent + unitPadding;
         
         int x = glyphAtlasX + atlasPadding + unitMargin - unitPadding;
         int y = glyphAtlasY + atlasPadding + unitMargin - unitPadding;
         
         data->u1[i] = x / (float)atlasWidth;
         data->v1[i] = y / (float)atlasHeight;
         data->u2[i] = (x + data->w[i]) / (float)atlasWidth;
         data->v2[i] = (y + data->h[i]) / (float)atlasHeight;
     }
     
     return make_pair(data, atlas);
 }
Esempio n. 25
0
void ewol::resource::TexturedFont::init(const std::string& _fontName) {
	std::unique_lock<std::recursive_mutex> lock(m_mutex);
	ewol::resource::Texture::init(_fontName);
	EWOL_DEBUG("Load font : '" << _fontName << "'" );

	m_font[0] = nullptr;
	m_font[1] = nullptr;
	m_font[2] = nullptr;
	m_font[3] = nullptr;
	
	m_modeWraping[0] = ewol::font::Regular;
	m_modeWraping[1] = ewol::font::Regular;
	m_modeWraping[2] = ewol::font::Regular;
	m_modeWraping[3] = ewol::font::Regular;
	
	m_lastGlyphPos[0].setValue(1,1);
	m_lastGlyphPos[1].setValue(1,1);
	m_lastGlyphPos[2].setValue(1,1);
	m_lastGlyphPos[3].setValue(1,1);
	
	m_lastRawHeigh[0] = 0;
	m_lastRawHeigh[1] = 0;
	m_lastRawHeigh[2] = 0;
	m_lastRawHeigh[3] = 0;
	
	int32_t tmpSize = 0;
	// extarct name and size :
	const char * tmpData = _fontName.c_str();
	const char * tmpPos = strchr(tmpData, ':');
	
	if (tmpPos == nullptr) {
		m_size = 1;
		EWOL_CRITICAL("Can not parse the font name : \"" << _fontName << "\" ??? ':' " );
		return;
	} else {
		if (sscanf(tmpPos+1, "%d", &tmpSize)!=1) {
			m_size = 1;
			EWOL_CRITICAL("Can not parse the font name : \"" << _fontName << "\"  == > size ???");
			return;
		}
	}
	std::string localName(_fontName, 0, (tmpPos - tmpData));
	if (tmpSize>400) {
		EWOL_ERROR("Font size too big ==> limit at 400 when exxeed ==> error : " << tmpSize << "==>30");
		tmpSize = 30;
	}
	m_size = tmpSize;
	
	std::vector<std::string> folderList;
	if (true == ewol::getContext().getFontDefault().getUseExternal()) {
		#if defined(__TARGET_OS__Android)
			folderList.push_back("ROOT:system/fonts");
		#elif defined(__TARGET_OS__Linux)
			folderList.push_back("ROOT:usr/share/fonts");
		#endif
	}
	std::string applicationBaseFont = ewol::getContext().getFontDefault().getFolder();
	std::vector<std::string> applicationBaseFontList = etk::FSNodeExplodeMultiplePath(applicationBaseFont);
	for (auto &it : applicationBaseFontList) {
		folderList.push_back(it);
	}
	for (size_t folderID=0; folderID<folderList.size() ; folderID++) {
		etk::FSNode myFolder(folderList[folderID]);
		// find the real Font name :
		std::vector<std::string> output;
		myFolder.folderGetRecursiveFiles(output);
		std::vector<std::string> split = etk::split(localName, ';');
		EWOL_INFO("try to find font named : " << split << " in: " << myFolder);
		//EWOL_CRITICAL("parse string : " << split);
		bool hasFindAFont = false;
		for (size_t jjj=0; jjj<split.size(); jjj++) {
			EWOL_INFO("    try with : '" << split[jjj] << "'");
			for (size_t iii=0; iii<output.size(); iii++) {
				//EWOL_DEBUG(" file : " << output[iii]);
				if(    true == etk::end_with(output[iii], split[jjj]+"-"+"bold"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"-"+"b"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"-"+"bd"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"bold"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"bd"+".ttf", false)
				    || true == etk::end_with(output[iii], split[jjj]+"b"+".ttf", false)) {
					EWOL_INFO(" find Font [Bold]        : " << output[iii]);
					m_fileName[ewol::font::Bold] = output[iii];
					hasFindAFont=true;
				} else if(    true == etk::end_with(output[iii], split[jjj]+"-"+"oblique"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"italic"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"Light"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"i"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"oblique"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"italic"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"light"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"i"+".ttf", false)) {
					EWOL_INFO(" find Font [Italic]      : " << output[iii]);
					m_fileName[ewol::font::Italic] = output[iii];
					hasFindAFont=true;
				} else if(    true == etk::end_with(output[iii], split[jjj]+"-"+"bolditalic"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"boldoblique"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"bi"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"z"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"bolditalic"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"boldoblique"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"bi"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"z"+".ttf", false)) {
					EWOL_INFO(" find Font [Bold-Italic] : " << output[iii]);
					m_fileName[ewol::font::BoldItalic] = output[iii];
					hasFindAFont=true;
				} else if(    true == etk::end_with(output[iii], split[jjj]+"-"+"regular"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"-"+"r"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"regular"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+"r"+".ttf", false)
				           || true == etk::end_with(output[iii], split[jjj]+".ttf", false)) {
					EWOL_INFO(" find Font [Regular]     : " << output[iii]);
					m_fileName[ewol::font::Regular] = output[iii];
					hasFindAFont=true;
				}
			}
			if (hasFindAFont == true) {
				EWOL_INFO("    find this font : '" << split[jjj] << "'");
				break;
			} else if (jjj == split.size()-1) {
				EWOL_ERROR("Find NO font in the LIST ... " << split);
			}
		}
		if (hasFindAFont == true) {
			EWOL_INFO("    find this font : '" << folderList[folderID] << "'");
			break;
		} else if (folderID == folderList.size()-1) {
			EWOL_ERROR("Find NO font in the LIST ... " << folderList);
		}
	}
	// try to find the reference mode :
	enum ewol::font::mode refMode = ewol::font::Regular;
	for(int32_t iii=3; iii >= 0; iii--) {
		if (m_fileName[iii].size() != 0) {
			refMode = (enum ewol::font::mode)iii;
		}
	}
	
	EWOL_DEBUG("         set reference mode : " << refMode);
	// generate the wrapping on the preventing error
	for(int32_t iii=3; iii >= 0; iii--) {
		if (m_fileName[iii].size() != 0) {
			m_modeWraping[iii] = (enum ewol::font::mode)iii;
		} else {
			m_modeWraping[iii] = refMode;
		}
	}
	
	for (int32_t iiiFontId=0; iiiFontId<4 ; iiiFontId++) {
		if (m_fileName[iiiFontId].size() == 0) {
			EWOL_DEBUG("can not load FONT [" << iiiFontId << "] name : \"" << m_fileName[iiiFontId] << "\"  == > size=" << m_size );
			m_font[iiiFontId] = nullptr;
			continue;
		}
		EWOL_INFO("Load FONT [" << iiiFontId << "] name : \"" << m_fileName[iiiFontId] << "\"  == > size=" << m_size);
		m_font[iiiFontId] = ewol::resource::FontFreeType::create(m_fileName[iiiFontId]);
		if (m_font[iiiFontId] == nullptr) {
			EWOL_DEBUG("error in loading FONT [" << iiiFontId << "] name : \"" << m_fileName[iiiFontId] << "\"  == > size=" << m_size );
		}
	}
	for (int32_t iiiFontId=0; iiiFontId<4 ; iiiFontId++) {
		// set the bassic charset:
		m_listElement[iiiFontId].clear();
		if (m_font[iiiFontId] == nullptr) {
			continue;
		}
		m_height[iiiFontId] = m_font[iiiFontId]->getHeight(m_size);
		// TODO : basic font use 512 is better ...  == > maybe estimate it with the dpi ???
		setImageSize(ivec2(256,32));
		// now we can acces directly on the image
		m_data.clear(etk::Color<>(0x00000000));
	}
	// add error glyph
	addGlyph(0);
	// by default we set only the first AINSI char availlable
	for (int32_t iii=0x20; iii<0x7F; iii++) {
		EWOL_VERBOSE("Add clyph :" << iii);
		addGlyph(iii);
	}
	flush();
	EWOL_DEBUG("Wrapping properties : ");
	EWOL_DEBUG("    " << ewol::font::Regular << " == >" << getWrappingMode(ewol::font::Regular));
	EWOL_DEBUG("    " << ewol::font::Italic << " == >" << getWrappingMode(ewol::font::Italic));
	EWOL_DEBUG("    " << ewol::font::Bold << " == >" << getWrappingMode(ewol::font::Bold));
	EWOL_DEBUG("    " << ewol::font::BoldItalic << " == >" << getWrappingMode(ewol::font::BoldItalic));
}
Esempio n. 26
0
BOOL LLFont::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
{
	// Don't leak face objects.  This is also needed to deal with
	// changed font file names.
	if (mFTFace)
	{
		FT_Done_Face(mFTFace);
		mFTFace = NULL;
	}

	int error;

	error = FT_New_Face( gFTLibrary,
						 filename.c_str(),
						 0,
						 &mFTFace );

    if (error)
	{
		return FALSE;
	}

	mIsFallback = is_fallback;
	F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi

	error = FT_Set_Char_Size(mFTFace,    /* handle to face object           */
							0,       /* char_width in 1/64th of points  */
							(S32)(point_size*64),   /* char_height in 1/64th of points */
							(U32)horz_dpi,     /* horizontal device resolution    */
							(U32)vert_dpi);   /* vertical device resolution      */

	if (error)
	{
		// Clean up freetype libs.
		FT_Done_Face(mFTFace);
		mFTFace = NULL;
		return FALSE;
	}

	F32 y_max, y_min, x_max, x_min;
	F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
	F32 pixels_per_unit = pixels_per_em * ems_per_unit;

	// Get size of bbox in pixels
	y_max = mFTFace->bbox.yMax * pixels_per_unit;
	y_min = mFTFace->bbox.yMin * pixels_per_unit;
	x_max = mFTFace->bbox.xMax * pixels_per_unit;
	x_min = mFTFace->bbox.xMin * pixels_per_unit;
	mAscender = mFTFace->ascender * pixels_per_unit;
	mDescender = -mFTFace->descender * pixels_per_unit;
	mLineHeight = mFTFace->height * pixels_per_unit;

	S32 max_char_width = llround(0.5f + (x_max - x_min));
	S32 max_char_height = llround(0.5f + (y_max - y_min));

	mFontBitmapCachep->init(components, max_char_width, max_char_height);

	if (!mFTFace->charmap)
	{
		//llinfos << " no unicode encoding, set whatever encoding there is..." << llendl;
		FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
	}

	if (!mIsFallback)
	{
		// Add the default glyph
		addGlyph(0, 0);
	}

	mName = filename;
	mPointSize = point_size;

	return TRUE;
}
Esempio n. 27
0
void DatasetIsoline::initGeometry()
{
    int nx = m_properties["maingl"].get( Fn::Property::D_NX ).toInt();
    int ny = m_properties["maingl"].get( Fn::Property::D_NY ).toInt();
    int nz = m_properties["maingl"].get( Fn::Property::D_NZ ).toInt();
    float dx = m_properties["maingl"].get( Fn::Property::D_DX ).toFloat();
    float dy = m_properties["maingl"].get( Fn::Property::D_DY ).toFloat();
    float dz = m_properties["maingl"].get( Fn::Property::D_DZ ).toFloat();
    float ax = m_properties["maingl"].get( Fn::Property::D_ADJUST_X ).toFloat();
    float ay = m_properties["maingl"].get( Fn::Property::D_ADJUST_Y ).toFloat();
    float az = m_properties["maingl"].get( Fn::Property::D_ADJUST_Z ).toFloat();
    m_x = Models::getGlobal( Fn::Property::G_SAGITTAL ).toFloat();
    m_y = Models::getGlobal( Fn::Property::G_CORONAL ).toFloat();
    m_z = Models::getGlobal( Fn::Property::G_AXIAL ).toFloat();

    int xi = qMax( 0.0f, qMin( ( m_x - ax ) / dx, (float)nx - 1 ) );
    int yi = qMax( 0.0f, qMin( ( m_y - ay ) / dy, (float)ny - 1 ) );
    int zi = qMax( 0.0f, qMin( ( m_z - az ) / dz, (float)nz - 1 ) );

    float isoValue = m_properties["maingl"].get( Fn::Property::D_ISO_VALUE ).toFloat();
    bool interpolation = m_properties["maingl"].get( Fn::Property::D_INTERPOLATION ).toBool();
    m_color =  m_properties["maingl"].get( Fn::Property::D_COLOR ).value<QColor>();
    int stripeType = m_properties["maingl"].get( Fn::Property::D_ISOLINE_STRIPES ).toInt();

    std::vector<float>verts;
    std::vector<float>stripeVerts;
    std::vector<float>colors;
    std::vector<float>stripeColors;

    m_vertCountAxial = 0;
    m_vertCountCoronal = 0;
    m_vertCountSagittal = 0;

    if ( m_properties["maingl"].get( Fn::Property::D_RENDER_AXIAL ).toBool() )
    {
        std::vector<float>sliceData;
        std::vector<float>tmpVerts;
        std::vector<float>tmpVerts2;

        sliceData = extractAnatomyAxial( zi );
        MarchingSquares ms1( &sliceData, isoValue, nx, ny, dx, dy, interpolation );
        tmpVerts = ms1.run();
        if ( stripeType > 0 )
        {
            tmpVerts2 = ms1.runStripes( stripeType, 2 );
        }

        if ( tmpVerts.size() > 0 )
        {
            for ( unsigned int i = 0; i < tmpVerts.size() / 4; ++i )
            {
                addGlyph( verts, colors, tmpVerts[4*i] + ax, tmpVerts[4*i+1] + ay, m_z, tmpVerts[4*i+2] + ax, tmpVerts[4*i+3] + ay, m_z );
            }
            if ( stripeType > 0 )
            {
                for ( unsigned int i = 0; i < tmpVerts2.size() / 4; ++i )
                {
                    addGlyph( stripeVerts, stripeColors, tmpVerts2[4*i] + ax, tmpVerts2[4*i+1] + ay, m_z, tmpVerts2[4*i+2] + ax, tmpVerts2[4*i+3] + ay, m_z );
                }
            }
            m_vertCountAxial = verts.size() / 8;
            m_stripeVertCountAxial = stripeVerts.size() / 8;
        }
    }

    if ( m_properties["maingl"].get( Fn::Property::D_RENDER_CORONAL ).toBool() )
    {
        std::vector<float>sliceData;
        std::vector<float>tmpVerts;
        std::vector<float>tmpVerts2;

        sliceData = extractAnatomyCoronal( yi );
        MarchingSquares ms1( &sliceData, isoValue, nx, nz, dx, dz, interpolation );
        tmpVerts = ms1.run();
        if ( stripeType > 0 )
        {
            tmpVerts2 = ms1.runStripes( stripeType, 2 );
        }

        if ( tmpVerts.size() > 0 )
        {
            for ( unsigned int i = 0; i < tmpVerts.size() / 4; ++i )
            {
                addGlyph( verts, colors, tmpVerts[4*i] + ax, m_y, tmpVerts[4*i+1] + az, tmpVerts[4*i+2] + ax, m_y, tmpVerts[4*i+3] + az );
            }
            if ( stripeType > 0 )
            {
                for ( unsigned int i = 0; i < tmpVerts2.size() / 4; ++i )
                {
                    addGlyph( stripeVerts, stripeColors, tmpVerts2[4*i] + ax, m_y, tmpVerts2[4*i+1] + az, tmpVerts2[4*i+2] + ax, m_y, tmpVerts2[4*i+3] + az );
                }
            }
            m_vertCountCoronal = verts.size() / 8 - m_vertCountAxial;
            m_stripeVertCountCoronal = stripeVerts.size() / 8 - m_stripeVertCountAxial;
        }
    }

    if ( m_properties["maingl"].get( Fn::Property::D_RENDER_SAGITTAL ).toBool() )
    {
        std::vector<float>sliceData;
        std::vector<float>tmpVerts;
        std::vector<float>tmpVerts2;

        sliceData = extractAnatomySagittal( xi );
        MarchingSquares ms1( &sliceData, isoValue, ny, nz, dy, dz, interpolation );
        tmpVerts = ms1.run();
        if ( stripeType > 0 )
        {
            tmpVerts2 = ms1.runStripes( stripeType, 2 );
        }

        if ( tmpVerts.size() > 0 )
        {
            for ( unsigned int i = 0; i < tmpVerts.size() / 4; ++i )
            {
                addGlyph( verts, colors, m_x, tmpVerts[4*i] + ay, tmpVerts[4*i+1] + az, m_x, tmpVerts[4*i+2] + ay, tmpVerts[4*i+3] + az );
            }
            if ( stripeType > 0 )
            {
                for ( unsigned int i = 0; i < tmpVerts2.size() / 4; ++i )
                {
                    addGlyph( stripeVerts, stripeColors, m_x, tmpVerts2[4*i] + ay, tmpVerts2[4*i+1] + az, m_x, tmpVerts2[4*i+2] + ay, tmpVerts2[4*i+3] + az );
                }
            }
            m_vertCountSagittal = verts.size() / 8 - ( m_vertCountCoronal + m_vertCountAxial );
            m_stripeVertCountSagittal = stripeVerts.size() / 8 - ( m_stripeVertCountCoronal + m_stripeVertCountAxial );
        }
    }

    if ( verts.size() > 0 )
    {
        if( vbo0 )
        {
            GLFunctions::f->glDeleteBuffers( 1, &vbo0 );
        }
        GLFunctions::f->glGenBuffers( 1, &vbo0 );
        if( vbo1 )
        {
            GLFunctions::f->glDeleteBuffers( 1, &vbo1 );
        }
        GLFunctions::f->glGenBuffers( 1, &vbo1 );
        if( vbo2 )
        {
            GLFunctions::f->glDeleteBuffers( 1, &vbo2 );
        }
        GLFunctions::f->glGenBuffers( 1, &vbo2 );
        if( vbo3 )
        {
            GLFunctions::f->glDeleteBuffers( 1, &vbo3 );
        }
        GLFunctions::f->glGenBuffers( 1, &vbo3 );


        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, vbo0 );
        GLFunctions::f->glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof( float ), verts.data(), GL_DYNAMIC_DRAW );
        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, 0 );

        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, vbo1 );
        GLFunctions::f->glBufferData( GL_ARRAY_BUFFER, colors.size() * sizeof( float ), colors.data(), GL_DYNAMIC_DRAW );
        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, 0 );

        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, vbo2 );
        GLFunctions::f->glBufferData( GL_ARRAY_BUFFER, stripeVerts.size() * sizeof( float ), stripeVerts.data(), GL_DYNAMIC_DRAW );
        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, 0 );

        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, vbo3 );
        GLFunctions::f->glBufferData( GL_ARRAY_BUFFER, stripeColors.size() * sizeof( float ), stripeColors.data(), GL_DYNAMIC_DRAW );
        GLFunctions::f->glBindBuffer( GL_ARRAY_BUFFER, 0 );
    }
    m_dirty = false;
}
Esempio n. 28
0
osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());

    setFontResolution(fontRes);

    //
    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being  
    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct 
    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.  
    // Microsoft uses a private field for its symbol fonts
    //
    unsigned int charindex = charcode;
    if (_face->charmap != NULL)
    {
        if (_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
        {
            charindex |= 0xF000;
        }
    }

    FT_Error error = FT_Load_Char( _face, charindex, FT_LOAD_RENDER|FT_LOAD_NO_BITMAP|_flags );
    if (error)
    {
        osg::notify(osg::WARN) << "FT_Load_Char(...) error 0x"<<std::hex<<error<<std::dec<<std::endl;
        return 0;
    }


    FT_GlyphSlot glyphslot = _face->glyph;

    int pitch = glyphslot->bitmap.pitch;
    unsigned char* buffer = glyphslot->bitmap.buffer;

    unsigned int sourceWidth = glyphslot->bitmap.width;;
    unsigned int sourceHeight = glyphslot->bitmap.rows;
    
    unsigned int width = sourceWidth;
    unsigned int height = sourceHeight;

    osg::ref_ptr<osgText::Font::Glyph> glyph = new osgText::Font::Glyph;
    
    unsigned int dataSize = width*height;
    unsigned char* data = new unsigned char[dataSize];
    

    // clear the image to zeros.
    for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }

    glyph->setImage(width,height,1,
                    GL_ALPHA,
                    GL_ALPHA,GL_UNSIGNED_BYTE,
                    data,
                    osg::Image::USE_NEW_DELETE,
                    1);

    glyph->setInternalTextureFormat(GL_ALPHA);

    // copy image across to osgText::Glyph image.     
    switch(glyphslot->bitmap.pixel_mode)
    {
        case FT_PIXEL_MODE_MONO:
            for(int r=sourceHeight-1;r>=0;--r)
            {
                unsigned char* ptr = buffer+r*pitch;
                for(unsigned int c=0;c<sourceWidth;++c)
                {
                    (*data++)= (ptr[c >> 3] & (1 << (~c & 7))) ? 255 : 0;
                }
            }
            break;

        
        case FT_PIXEL_MODE_GRAY:
            for(int r=sourceHeight-1;r>=0;--r)
            {
                unsigned char* ptr = buffer+r*pitch;
                for(unsigned int c=0;c<sourceWidth;++c,++ptr)
                {
                    (*data++)=*ptr;
                }
            }
            break;
            
        default:
            osg::notify(osg::WARN) << "FT_Load_Char(...) returned bitmap with unknown pixel_mode " << glyphslot->bitmap.pixel_mode << std::endl;
    }


    FT_Glyph_Metrics* metrics = &(glyphslot->metrics);

    glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left.
    glyph->setHorizontalAdvance((float)metrics->horiAdvance/64.0f);
    glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX/64.0f,(float)(metrics->vertBearingY-metrics->height)/64.0f)); // top middle.
    glyph->setVerticalAdvance((float)metrics->vertAdvance/64.0f);

    addGlyph(fontRes,charcode,glyph.get());
    
//    cout << "      in getGlyph() implementation="<<this<<"  "<<_filename<<"  facade="<<_facade<<endl;

    return glyph.get();

}