Beispiel #1
0
TtfFont::TheGlyph &TtfFont::getGlyph(uint32_t fontSize, char32_t character)
{
    SizeCharMap::iterator fSize = m_charMap.find(fontSize);
    if(fSize != m_charMap.end())
    {
        CharMap::iterator rc = fSize->second.find(character);
        if(rc != fSize->second.end())
            return rc->second;
        return loadGlyph(fontSize, character);
    }

    return loadGlyph(fontSize, character);
}
void QFontEngineQPF::ensureGlyphsLoaded(const QGlyphLayout *glyphs, int len)
{
    if (readOnly)
        return;
    bool locked = false;
    for (int i = 0; i < len; ++i) {
        if (!glyphs[i].glyph)
            continue;
        const Glyph *g = findGlyph(glyphs[i].glyph);
        if (g)
            continue;
        if (!locked) {
            if (!lockFile())
                return;
            locked = true;
            g = findGlyph(glyphs[i].glyph);
            if (g)
                continue;
        }
        loadGlyph(glyphs[i].glyph);
    }
    if (locked) {
        unlockFile();
#if defined(DEBUG_FONTENGINE)
        qDebug() << "Finished rendering glyphs\n";
#endif
    }
}
Beispiel #3
0
	void Font::loadFont( const char* xmlFile )
	{
		XMLParser parser( xmlFile );
		XMLDocument& doc = parser.getDocument();		
		
		if( !doc.Error() )
		{		
			XMLNode* root = doc.FirstChildElement( "FontDefinition" );
			XMLNode* fontInfo = root->FirstChildElement( "FontInfo" );
			m_fontName = parser.getXMLAttributeAsString( fontInfo, "name", "" );
			m_fontLocale = parser.getXMLAttributeAsString( fontInfo, "local", "en" );
			m_pixelHeight = parser.getXMLAttributeAsInt( fontInfo, "cellPixelHeight", 1 );


			XMLNode* element; 
			for( element = root->FirstChildElement( "Glyph" ); element != 0; element = element->NextSiblingElement( "Glyph" ) )
			{
				Glyph g = loadGlyph( parser, element );
				m_glyphs.insert( std::pair< unsigned char, Glyph >( g.ucsIndex, g ) );
			}
		}
		else
		{
			MonkyException::simpleErrorMessageBox( "Failed to load font", "File could not be opened" );
		}
	}
Beispiel #4
0
bool CPetRemote::loadGlyphs(const Common::Array<uint> &indexes) {
	for (uint idx = 0; idx < indexes.size(); ++idx) {
		if (!loadGlyph(indexes[idx]))
			return false;
	}

	return true;
}
Beispiel #5
0
Glyph::Glyph(Parameter parameter, const LibraryParameter &library) :
        slot(loadGlyph(parameter.character, library.face)),
        size(slot->bitmap.width, slot->bitmap.rows),
        bearing(slot->bitmap_left, slot->bitmap_top),
        advance(slot->advance.x, slot->advance.y),
        texture(Image(size, slot->bitmap.buffer, Texture::InternalFormat::Red, Texture::Format::Red)) {

}
Beispiel #6
0
qreal ScFace::ScFaceData::glyphWidth(gid_type gl, qreal size) const
{
	if (gl >= CONTROL_GLYPHS)
		return 0.0;
	else if (! m_glyphWidth.contains(gl)) {
		loadGlyph(gl);
	}
	return m_glyphWidth[gl] * size;
}
 void setUpFreetype( unsigned int characterIndex)
 {
     FT_Error error = FT_Init_FreeType( &library);
     assert(!error);
     error = FT_New_Face( library, ARIAL_FONT_FILE, 0, &face);
     assert(!error);
     
     loadGlyph( characterIndex);
 }
//-----------------------------------------------------------
ofTexture ofTrueTypeFont::getStringTexture(const std::string& str, bool vflip) const{
    string str_valid;
	utf8::replace_invalid(str.begin(),str.end(),back_inserter(str_valid));
	vector<glyph> glyphs;
	vector<ofVec2f> glyphPositions;
	utf8::iterator<const char*> it(&str_valid.front(), &str_valid.front(), (&str_valid.back())+1);
	utf8::iterator<const char*> end((&str_valid.back())+1, &str_valid.front(), (&str_valid.back())+1);
	int	x = 0;
	int	y = 0;
	long height = 0;
	uint32_t prevC = 0;
	while(it != end){
		try{
			auto c = *it;
			if (c == '\n') {
				y += lineHeight;
				x = 0 ; //reset X Pos back to zero
				prevC = 0;
			} else {
				glyphs.push_back(loadGlyph(c));
				if(prevC>0){
					x += getKerning(c,prevC);
				}else if(settings.direction == ofTtfSettings::RightToLeft){
					x += glyphs.back().props.width;
				}
				glyphPositions.emplace_back(static_cast<float>(x), static_cast<float>(y));
				x += glyphs.back().props.advance * letterSpacing;
				height = max(height, glyphs.back().props.ymax + y + long(getLineHeight()));
			}
			++it;
			prevC = c;
		}catch(...){
			break;
		}
	}
	ofTexture tex;
	ofPixels totalPixels;
	totalPixels.allocate(x, height, OF_PIXELS_GRAY_ALPHA);
	//-------------------------------- clear data:
	totalPixels.set(0,255); // every luminance pixel = 255
	totalPixels.set(1,0);
	size_t i = 0;
	for(auto & g: glyphs){
		if(settings.direction == ofTtfSettings::LeftToRight){
			g.pixels.blendInto(totalPixels, glyphPositions[i].x, glyphPositions[i].y + getLineHeight() + g.props.ymin + getDescenderHeight() );
		}else{
			g.pixels.blendInto(totalPixels, x-glyphPositions[i].x, glyphPositions[i].y + getLineHeight() + g.props.ymin + getDescenderHeight() );
		}
		i++;
		if(i==glyphPositions.size()){
			break;
		}
	}
	tex.allocate(totalPixels);
	return tex;
}
Beispiel #9
0
Glyph Font::getGlyph(const char c){
	std::map<char, Glyph>::iterator it = glyphs.find(c);
	if(it != glyphs.end()){
		return it->second;
	}
	else{
		Glyph g = loadGlyph(c);
		return (glyphs[c] = g);
	}
}
Beispiel #10
0
FPoint ScFace::ScFaceData::glyphOrigin(gid_type gl, qreal sz) const
{
	if (gl == 0 || gl >= CONTROL_GLYPHS)
		return FPoint(0,0);
	else if (! m_glyphWidth.contains(gl)) {
		loadGlyph(gl);
	}
	const struct GlyphData & res(m_glyphOutline[gl]);
	return FPoint(res.x, res.y) * sz; 
}
Beispiel #11
0
FPointArray ScFace::ScFaceData::glyphOutline(gid_type gl, qreal sz) const
{ 
	if (gl >= CONTROL_GLYPHS)
		return FPointArray();
	else if (! m_glyphWidth.contains(gl)) {
		loadGlyph(gl);
	}
	FPointArray res = m_glyphOutline[gl].Outlines.copy();
	if (sz != 1.0)
		res.scale(sz, sz);
	return res;
}
Beispiel #12
0
void loadText()
{
   fontInit(20,0);
   
   width = 1024,height = 1024;
   int x = 0,y = 0,maxy = 0;

   unsigned char *lol = new unsigned char[width * height];
   memset(lol,0,width * height);

   for (int i = 32;i< 128;i++)
   {


      loadGlyph(i);

      int w = glyphs[i -32]->bitmap.width;
      int h = glyphs[i -32]->bitmap.rows;
      
      maxy = maxy > h ? maxy : h;

      if ((x + w) > width)
	 y+= maxy + 3,x = 0,maxy = 0;

      glyphsPos[i -32].x = x;
      glyphsPos[i -32].y = y;
      
      for (int l = 0;l<h;l++)
	 memcpy(lol + (l +y)*width + x,glyphs[i -32]->bitmap.buffer + l * w,w);

      x+=w + 3;
   }

   glActiveTexture(GL_TEXTURE1);
   GLuint texttext;;
   glGenTextures(1,&texttext);

   glBindTexture(GL_TEXTURE_2D,texttext);

   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
   glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,width,height,0,GL_ALPHA,GL_UNSIGNED_BYTE,lol );

   glUniform1i(TextUniform,1);
}
//-----------------------------------------------------------
ofTexture ofTrueTypeFont::getStringTexture(const std::string& str, bool vflip) const {
    vector<glyph> glyphs;
    vector<ofVec2f> glyphPositions;
    long height = 0;
    int width = 0;
    int lineWidth = 0;
    uint32_t prevC = 0;
    iterateString(str, 0, 0, vflip, [&](uint32_t c, ofVec2f pos) {
        try {
            if (c != '\n') {
                auto g = loadGlyph(c);
                glyphs.push_back(g);
                int x = pos.x + g.props.xmin;
                int y = g.props.ymax + pos.y;
                glyphPositions.emplace_back(x, y);
                lineWidth += glyphs.back().props.advance * letterSpacing;
                width = max(width, lineWidth);
                height = max(height, y + long(getLineHeight()));
            } else {
                lineWidth = 0;
            }
        } catch(...) {
        }
    });

    ofTexture tex;
    ofPixels totalPixels;
    totalPixels.allocate(width, height, OF_PIXELS_GRAY_ALPHA);
    //-------------------------------- clear data:
    totalPixels.set(0,255); // every luminance pixel = 255
    totalPixels.set(1,0);
    size_t i = 0;
    for(auto & g: glyphs) {
        if(settings.direction == ofTtfSettings::LeftToRight) {
            g.pixels.blendInto(totalPixels, glyphPositions[i].x, glyphPositions[i].y + getLineHeight() + g.props.ymin + getDescenderHeight() );
        } else {
            g.pixels.blendInto(totalPixels, width-glyphPositions[i].x, glyphPositions[i].y + getLineHeight() + g.props.ymin + getDescenderHeight() );
        }
        i++;
        if(i==glyphPositions.size()) {
            break;
        }
    }
    tex.allocate(totalPixels);
    return tex;
}
Beispiel #14
0
GlyphMetrics ScFace::ScFaceData::glyphBBox(gid_type gl, qreal sz) const
{
	GlyphMetrics res;
	if (gl == 0 || gl >= CONTROL_GLYPHS)
	{	res.width   = glyphWidth(gl, sz);
		res.ascent  = (gl == 0? ascent(sz) : 0);
		res.descent = 0;
		return res;
	}
	else if (! m_glyphWidth.contains(gl)) {
		loadGlyph(gl);
	}
	const struct GlyphData & data(m_glyphOutline[gl]);
	res.width = data.bbox_width * sz;
	res.ascent = data.bbox_ascent * sz;
	res.descent = data.bbox_descent * sz;	
	return res;
}
//-----------------------------------------------------------
ofVec2f ofTrueTypeFont::getFirstGlyphPosForTexture(const std::string & str, bool vflip) const {
    if(!str.empty()) {
        try {
            auto c = *ofUTF8Iterator(str).begin();
            if (c == '\n') {
                return {0.f, 0.f};
            } else {
                auto g = loadGlyph(c);
                if(settings.direction == ofTtfSettings::LeftToRight) {
                    return {-float(g.props.xmin), getLineHeight() + g.props.ymin + getDescenderHeight()};
                } else {
                    return {-float(g.props.xmin), getLineHeight() + g.props.ymin + getDescenderHeight()};
                }
            }
        } catch(...) {
            return {0.f, 0.f};
        }
    }
}
Beispiel #16
0
FPointArray ScFace::ScFaceData::glyphOutline(uint gl, qreal sz) const 
{ 
	if (gl >= CONTROL_GLYPHS)
		return FPointArray();
	else if (gl == 0) {
		sz *= 10;
		FPointArray sq;
		sq.addQuadPoint(0,0,0,0,sz,0,sz,0);
		sq.addQuadPoint(sz,0,sz,0,sz,sz,sz,sz);
		sq.addQuadPoint(sz,sz,sz,sz,0,sz,0,sz);
		sq.addQuadPoint(0,sz,0,sz,0,0,0,0);
		return sq;
	}
	else if (! m_glyphWidth.contains(gl)) {
		loadGlyph(gl);
	}
	FPointArray res = m_glyphOutline[gl].Outlines.copy();
	if (sz != 1.0)
		res.scale(sz, sz);
	return res;
}
Beispiel #17
0
int FTPixmapFont::getWidth( const char* text )
{
  if( text == 0 )
    return 0;

  int w= 0;
  for(;;)
    {
    int ch= (unsigned char) *(text++);
    if( ch == 0 )
      break;

    loadGlyph(ch);
    if( pixmaps[ch] == 0 )
      continue;

    w+= pixmaps[ch]->getAdvance();
    }

  return w / 64;
}
Beispiel #18
0
const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const
{
    // Get the page corresponding to the character size
    GlyphTable& glyphs = m_pages[characterSize].glyphs;

    // Build the key by combining the code point and the bold flag
    Uint32 key = ((bold ? 1 : 0) << 31) | codePoint;

    // Search the glyph into the cache
    GlyphTable::const_iterator it = glyphs.find(key);
    if (it != glyphs.end())
    {
        // Found: just return it
        return it->second;
    }
    else
    {
        // Not found: we have to load it
        Glyph glyph = loadGlyph(codePoint, characterSize, bold);
        return glyphs.insert(std::make_pair(key, glyph)).first->second;
    }
}
Beispiel #19
0
const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, float outlineThickness) const
{
    // Get the page corresponding to the character size
    GlyphTable& glyphs = m_pages[characterSize].glyphs;

    // Build the key by combining the glyph index (based on code point), bold flag, and outline thickness
    Uint64 key = combine(outlineThickness, bold, FT_Get_Char_Index(static_cast<FT_Face>(m_face), codePoint));

    // Search the glyph into the cache
    GlyphTable::const_iterator it = glyphs.find(key);
    if (it != glyphs.end())
    {
        // Found: just return it
        return it->second;
    }
    else
    {
        // Not found: we have to load it
        Glyph glyph = loadGlyph(codePoint, characterSize, bold, outlineThickness);
        return glyphs.emplace(key, glyph).first->second;
    }
}
Beispiel #20
0
const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, float outlineThickness) const
{
    // Get the page corresponding to the character size
    GlyphTable& glyphs = m_pages[characterSize].glyphs;

    // Build the key by combining the code point, bold flag, and outline thickness
    Uint64 key = (static_cast<Uint64>(*reinterpret_cast<Uint32*>(&outlineThickness)) << 32)
               | (static_cast<Uint64>(bold ? 1 : 0) << 31)
               |  static_cast<Uint64>(codePoint);

    // Search the glyph into the cache
    GlyphTable::const_iterator it = glyphs.find(key);
    if (it != glyphs.end())
    {
        // Found: just return it
        return it->second;
    }
    else
    {
        // Not found: we have to load it
        Glyph glyph = loadGlyph(codePoint, characterSize, bold, outlineThickness);
        return glyphs.insert(std::make_pair(key, glyph)).first->second;
    }
}
Beispiel #21
0
static void msdfgen_hello_world()
{
	msdfgen::FreetypeHandle* ft = msdfgen::initializeFreetype();
	if ( ft )
	{
		msdfgen::FontHandle* font = loadFont( ft, "OpenSans.ttf" );
		if ( font )
		{
			msdfgen::Shape shape;
			if ( loadGlyph( shape, font, 'A' ))
			{
				shape.normalize();
				// max. angle
				edgeColoringSimple( shape, 3.0 );
				// image width, height
				msdfgen::Bitmap<msdfgen::FloatRGB> msdf( 32, 32 );
				// range, scale, translation
				generateMSDF( msdf, shape, 4.0, 1.0, msdfgen::Vector2( 4.0, 4.0 ));
			}
			destroyFont( font );
		}
		deinitializeFreetype( ft );
	}
}
Beispiel #22
0
	void Font::loadGlyph(const UTF8String & str) {
		UCodePoint codePoint;
		for ( auto it = str.getBegin(); str.iterate(&it, &codePoint);) {
			loadGlyph(codePoint);
		}
	}
bool ofTrueTypeFont::load(const ofTtfSettings & _settings){
	#if defined(TARGET_ANDROID)
	ofAddListener(ofxAndroidEvents().unloadGL,this,&ofTrueTypeFont::unloadTextures);
	ofAddListener(ofxAndroidEvents().reloadGL,this,&ofTrueTypeFont::reloadTextures);
	#endif

	initLibraries();
	settings = _settings;
	if( settings.dpi == 0 ){
		settings.dpi = ttfGlobalDpi;
	}

	bLoadedOk = false;

	//--------------- load the library and typeface
	FT_Face loadFace;
	if(!loadFontFace(settings.fontName,settings.fontSize,loadFace,settings.fontName)){
		return false;
	}
	face = std::shared_ptr<struct FT_FaceRec_>(loadFace,FT_Done_Face);

	if(settings.ranges.empty()){
		settings.ranges.push_back(ofUnicode::Latin1Supplement);
	}
	int border = 1;


	FT_Set_Char_Size( face.get(), settings.fontSize << 6, settings.fontSize << 6, settings.dpi, settings.dpi);
	fontUnitScale = (float(settings.fontSize * settings.dpi)) / (72 * face->units_per_EM);
	lineHeight = face->height * fontUnitScale;
	ascenderHeight = face->ascender * fontUnitScale;
	descenderHeight = face->descender * fontUnitScale;
	glyphBBox.set(face->bbox.xMin * fontUnitScale,
				   face->bbox.yMin * fontUnitScale,
				  (face->bbox.xMax - face->bbox.xMin) * fontUnitScale,
				  (face->bbox.yMax - face->bbox.yMin) * fontUnitScale);

	//--------------- initialize character info and textures
	auto nGlyphs = std::accumulate(settings.ranges.begin(), settings.ranges.end(), 0u,
			[](uint32_t acc, ofUnicode::range range){
				return acc + range.getNumGlyphs();
			});
	cps.resize(nGlyphs);
	if(settings.contours){
		charOutlines.resize(nGlyphs);
		charOutlinesNonVFlipped.resize(nGlyphs);
		charOutlinesContour.resize(nGlyphs);
		charOutlinesNonVFlippedContour.resize(nGlyphs);
	}else{
		charOutlines.resize(1);
	}

	vector<ofTrueTypeFont::glyph> all_glyphs;

	uint32_t areaSum=0;

	//--------------------- load each char -----------------------
	auto i = 0u;
	for(auto & range: settings.ranges){
		for (uint32_t g = range.begin; g <= range.end; g++, i++){
			all_glyphs.push_back(loadGlyph(g));
			all_glyphs[i].props.characterIndex	= i;
			glyphIndexMap[g] = i;
			cps[i] = all_glyphs[i].props;
			areaSum += (cps[i].tW+border*2)*(cps[i].tH+border*2);

			if(settings.contours){
				if(printVectorInfo){
					std::string str;
					ofAppendUTF8(str,g);
					ofLogNotice("ofTrueTypeFont") <<  "character " << str;
				}

				//int character = i + NUM_CHARACTER_TO_START;
				charOutlines[i] = makeContoursForCharacter( face.get() );
				charOutlinesContour[i] = charOutlines[i];
				charOutlinesContour[i].setFilled(false);
				charOutlinesContour[i].setStrokeWidth(1);

				charOutlinesNonVFlipped[i] = charOutlines[i];
				charOutlinesNonVFlipped[i].translate(ofVec3f(0,cps[i].height));
				charOutlinesNonVFlipped[i].scale(1,-1);
				charOutlinesNonVFlippedContour[i] = charOutlines[i];
				charOutlinesNonVFlippedContour[i].setFilled(false);
				charOutlinesNonVFlippedContour[i].setStrokeWidth(1);


				if(settings.simplifyAmt>0){
					charOutlines[i].simplify(settings.simplifyAmt);
					charOutlinesNonVFlipped[i].simplify(settings.simplifyAmt);
					charOutlinesContour[i].simplify(settings.simplifyAmt);
					charOutlinesNonVFlippedContour[i].simplify(settings.simplifyAmt);
				}
			}
		}
	}

	vector<ofTrueTypeFont::glyphProps> sortedCopy = cps;
	sort(sortedCopy.begin(),sortedCopy.end(),[](const ofTrueTypeFont::glyphProps & c1, const ofTrueTypeFont::glyphProps & c2){
		if(c1.tH == c2.tH) return c1.tW > c2.tW;
		else return c1.tH > c2.tH;
	});

	// pack in a texture, algorithm to calculate min w/h from
	// http://upcommons.upc.edu/pfc/bitstream/2099.1/7720/1/TesiMasterJonas.pdf
	//ofLogNotice("ofTrueTypeFont") << "loadFont(): areaSum: " << areaSum

	bool packed = false;
	float alpha = logf(areaSum)*1.44269f;
	int w;
	int h;
	while(!packed){
		w = pow(2,floor((alpha/2.f) + 0.5f)); // there doesn't seem to be a round in cmath for windows.
		//w = pow(2,round(alpha/2.f));
		h = w;//pow(2,round(alpha - round(alpha/2.f)));
		int x=0;
		int y=0;
		auto maxRowHeight = sortedCopy[0].tH + border*2;
		packed = true;
		for(auto & glyph: sortedCopy){
			if(x+glyph.tW + border*2>w){
				x = 0;
				y += maxRowHeight;
				maxRowHeight = glyph.tH + border*2;
				if(y + maxRowHeight > h){
					alpha++;
					packed = false;
					break;
				}
			}
			x+= glyph.tW + border*2;
		}

	}



	ofPixels atlasPixelsLuminanceAlpha;
	atlasPixelsLuminanceAlpha.allocate(w,h,OF_PIXELS_GRAY_ALPHA);
	atlasPixelsLuminanceAlpha.set(0,255);
	atlasPixelsLuminanceAlpha.set(1,0);


	int x=0;
	int y=0;
	auto maxRowHeight = sortedCopy[0].tH + border*2;
	for(auto & glyph: sortedCopy){
		ofPixels & charPixels = all_glyphs[glyph.characterIndex].pixels;

		if(x+glyph.tW + border*2>w){
			x = 0;
			y += maxRowHeight;
			maxRowHeight = glyph.tH + border*2;
		}

		cps[glyph.characterIndex].t1		= float(x + border)/float(w);
		cps[glyph.characterIndex].v1		= float(y + border)/float(h);
		cps[glyph.characterIndex].t2		= float(cps[glyph.characterIndex].tW + x + border)/float(w);
		cps[glyph.characterIndex].v2		= float(cps[glyph.characterIndex].tH + y + border)/float(h);
		charPixels.pasteInto(atlasPixelsLuminanceAlpha,x+border,y+border);
		x+= glyph.tW + border*2;
	}
	texAtlas.allocate(atlasPixelsLuminanceAlpha,false);
	texAtlas.setRGToRGBASwizzles(true);

	if(settings.antialiased && settings.fontSize>20){
		texAtlas.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR);
	}else{
		texAtlas.setTextureMinMagFilter(GL_NEAREST,GL_NEAREST);
	}
	texAtlas.loadData(atlasPixelsLuminanceAlpha);
	bLoadedOk = true;
	return true;
}
Beispiel #24
0
void FTPixmapFont::load( int from /* = 0 */, int to /* = 255 */ )
{
  for( int i= from; i <= to; ++i )
    loadGlyph(i);
}
Beispiel #25
0
/**
    \fn DIA_ocrGen
    \brief Dialog to select input & output files before calling the actual ocr engine
*/
uint8_t DIA_ocrGen(void)
{

  vobSubParam subparam={NULL,0,0};
  char *srtFileName=NULL;
  char *glyphFileName=NULL;
  admGlyph head(16,16);
  char *globalGlyph=NULL;
  uint32_t globalGlyphOn=0;
  ADM_OCR_SOURCE source;
  
  memset(&source,0,sizeof(source));
  
  source.type=ADM_OCR_TYPE_VOBSUB;
  source.subparam=&subparam;
  
  prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&globalGlyphOn);
  if(globalGlyphOn)
  {
     prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyph);
     if(!*globalGlyph)
     {
        ADM_dezalloc(globalGlyph);
        globalGlyph=NULL; 
     }
  }

  if(globalGlyph)
  {
    glyphFileName=globalGlyph;
  }
_again:  
  // Fist build a dialogFactory to get input and output files
  diaElemButton   selectIdx(QT_TR_NOOP("Select idx file:"), cb_idx,&subparam,NULL);
  diaElemFile     selectGlyph(1,&glyphFileName,QT_TR_NOOP("Use GlyphSet (optional):"), NULL, QT_TR_NOOP("Select GlyphSet file"));
  diaElemFile     selectSrt(1,&srtFileName,QT_TR_NOOP("Output SRT file"), NULL, QT_TR_NOOP("Save SRT file"));
  
  diaElem *elems[]={&selectIdx,&selectSrt,&selectGlyph};
  
   uint32_t n=3;
   if(globalGlyph)
   {
     n--; // Remove glyph from dialog
   }
  
    if(!diaFactoryRun(QT_TR_NOOP("Select input and ouput files"),n,elems))
        {
          cleanupSub(&source);
          if(srtFileName )ADM_dezalloc(srtFileName);
          srtFileName=NULL;
          destroyGlyphTree(&head);
          return 0;
        }
        if(!ADM_fileExist(subparam.subname))
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
          goto _again; 
        }
        if(!srtFileName || !*srtFileName)
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid output SRT file."));
          goto _again; 
        }
         if(glyphFileName && *glyphFileName)
         {
           if(!ADM_fileExist(glyphFileName))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
              goto _again; 
            }
            // Purge previous glyph set if any
            destroyGlyphTree(&head);
            uint32_t nb;
            printf("[OCR] Loading glyphset :<%s>\n",glyphFileName);
            if(!loadGlyph(glyphFileName,&head,&nb))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Cannot load the glyphset file."));
              goto _again;               
            }
            printf("[GLYPH] Found %u glyph\n");
         }
        // We have our SRT and our idx/sub files : Go go go
         
    if(ADM_ocr_engine(source,srtFileName,&head))
    {
        // Save glyph set 
        if(globalGlyph)
        {
          uint32_t nb=1;
           saveGlyph(globalGlyph,&head,nb);
        }
        else
        {
            char *save=NULL;
            uint32_t nb=1;
              diaElemFile     selectSave(1,&save,QT_TR_NOOP("GlyphSet filename"), NULL, QT_TR_NOOP("Save GlyphSet file"));
              diaElem *elems2[]={&selectSave};
            if(diaFactoryRun(QT_TR_NOOP("Save Glyph"),1,elems2))
            {
              saveGlyph(save,&head,nb);
            }
            if(save) ADM_dezalloc(save);
        }
    }

  cleanupSub(&source);
  if(srtFileName )ADM_dezalloc(srtFileName);
  srtFileName=NULL;
  destroyGlyphTree(&head);
  return 1;  
}
/**
    \fn DIA_glyphEdit
    \brief Dialog to edit glyph
*/
uint8_t DIA_glyphEdit(void)
{
  char *glyphName;
  admGlyph head(1,1);
  
  
  uint32_t nbGlyph=0;
  uint8_t ret=0;
  // First select a file
  
   GUI_FileSelRead(QT_TR_NOOP("Select GlyphFile to edit"), &glyphName);
  if(!glyphName) return 0;
  
  // Try to load it
  if(!loadGlyph(glyphName,&head,&nbGlyph) || !nbGlyph)
  {
    destroyGlyphTree(&head);
    return 0;
  }
  // Convert the linear glyph to glyph array
  admGlyph *glyphArray[nbGlyph];
  admGlyph *cur=head.next;
  uint32_t idx=0;
  while(cur)
  {
     glyphArray[idx++]=cur;
     cur=cur->next;
  }
  ADM_assert(idx<=nbGlyph);
  nbGlyph=idx;
  // Glyph loaded, here we go
  currentGlyph=head.next;
  dialog=create_dialog1 ();
  gtk_register_dialog(dialog);
  
  // Register callbacks
#define ASSOCIATE(x,y)   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y)
#define CONNECT(x,y,z) 	gtk_signal_connect(GTK_OBJECT(WID(x)), #y,GTK_SIGNAL_FUNC(z),   NULL);
#define ACTION_PREV 10
#define ACTION_NEXT 20
#define ACTION_PREV_EMPTY 30
#define ACTION_NEXT_EMPTY 40
#define ACTION_SAVE 50
#define ACTION_DELETE 60
#define ACTION_ACTIVATE 70
#define ACTION_SEARCH 80
#define ACTION_REWIND 90
  
  ASSOCIATE(buttonPrev,ACTION_PREV);
  ASSOCIATE(buttonNext,ACTION_NEXT);
  ASSOCIATE(buttonEmptyPrev,ACTION_PREV_EMPTY);
  ASSOCIATE(buttonNextEmpty,ACTION_NEXT_EMPTY);
  ASSOCIATE(buttonSave,ACTION_SAVE);
  ASSOCIATE(buttonDelete,ACTION_DELETE);
  ASSOCIATE(buttonSearch,ACTION_SEARCH);
  ASSOCIATE(buttonRewind,ACTION_REWIND);
  
  
  CONNECT(drawingarea1,expose_event,glyphDraw);
  CONNECT(entry1,activate,glyphActivate);
  
  gtk_widget_show(dialog);
  glyphUpdate();
  while(1)
  {
   gint b=gtk_dialog_run(GTK_DIALOG(dialog));
    switch(b)
    {
      case ACTION_REWIND:
                            currentGlyph=head.next;
                            glyphUpdate();
                            continue;
      case ACTION_SEARCH:
                          {
                          char *tomatch=NULL;
                          {
                            // Dialog Factory to the rescue ! 
                              
                              diaElemText txt(&tomatch,QT_TR_NOOP("String"),NULL);
                              diaElem *elems[]={&txt};
                              if(!diaFactoryRun(QT_TR_NOOP("Search string"),1,elems))
                              {
                                  continue;
                                  break;
                              }
                          }
                          printf("Searched string <%s>\n",tomatch);
                          
                          while(currentGlyph->next)
                          {
                             currentGlyph=currentGlyph->next;
                             glyphUpdate();
                             
                             if(currentGlyph->code)
                             {
                                printf("%s vs %s\n",currentGlyph->code,tomatch);
                                if(!strcmp(currentGlyph->code,tomatch))
                                {
                                  
                                  glyphUpdate();
                                  break;  
                                }
                             }
                          }
                          ADM_dezalloc(tomatch);
                          if(!currentGlyph->next)
                                GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs"));
                          }
                          
                          continue;
                          break;
                        ;
      case ACTION_PREV: 
                        printf("PREV\n");
                        if(currentGlyph!=head.next)
                        {
                           admGlyph *father;
                           father=glyphSearchFather(currentGlyph,&head);
                           if(father)
                           {
                               currentGlyph=father;
                               glyphUpdate();
                           }
                          
                        }
                        continue;break;
      case ACTION_NEXT: 
                        printf("NEXT\n");
                        if(currentGlyph->next)
                        {
                          currentGlyph=currentGlyph->next; 
                          glyphUpdate();
                        }
                        continue;break; 
      case ACTION_NEXT_EMPTY: 
                        printf("NEXT EMPTY\n");
                        while(1)
                        {
                            if(currentGlyph->next)
                            {
                              currentGlyph=currentGlyph->next; 
                              glyphUpdate();
                              if(!currentGlyph->code || !*(currentGlyph->code))
                              {
                                break;
                              }
                            }
                            else 
                            {
                              GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs"));
                              break;
                            }
                        }
                        continue;break; 
        case ACTION_PREV_EMPTY: 
                        printf("PREV EMPTY\n");
                        while(1)
                        {
                            if(currentGlyph!=head.next)
                            {
                              admGlyph *father;
                              father=glyphSearchFather(currentGlyph,&head);
                              if(father)
                              {
                                  currentGlyph=father;
                                  glyphUpdate();
                                   if(!currentGlyph->code || !*(currentGlyph->code))
                                    {
                                      break;
                                    }
                                  continue;
                              } 
                            } 
                            GUI_Error_HIG(QT_TR_NOOP("Head reached"),QT_TR_NOOP("No more glyphs"));
                            break;
                        }
                        continue;break;
      case ACTION_SAVE:
                    saveGlyph(glyphName,&head,nbGlyph);
                    continue;break;
      case ACTION_DELETE:
                  {
                      admGlyph *father;
                      father=glyphSearchFather(currentGlyph,&head);
                      ADM_assert(father);
                      father->next=currentGlyph->next;
                      delete currentGlyph;
                      
                      currentGlyph=father;
                        if(father==&head && head.next)
                          currentGlyph=head.next;
                      nbGlyph--;
                      glyphUpdate();
                      continue;break; 
                  }
      case ACTION_ACTIVATE:
                  {
                      const gchar  *old;
                      if(currentGlyph->code) delete [] currentGlyph->code;
                      currentGlyph->code=NULL;
                      // Retrieve new one
                      old=gtk_entry_get_text (GTK_ENTRY (WID(entry1)));
                      
                      if(old && strlen(old))
                      {
                        currentGlyph->code=new char[strlen(old)+1];
                        strcpy(currentGlyph->code,old);
                      }
                    
                  }
                        continue;break; 
    }
    break; // exit while(1)
  }
  
  gtk_unregister_dialog(dialog);
  gtk_widget_destroy(dialog);
  
  destroyGlyphTree(&head);
  return ret;

}
Beispiel #27
0
/**
    \fn DIA_ocrDvb
    \brief Dialog to select input & output files before calling the actual ocr engine
*/
uint8_t DIA_ocrDvb(void)
{

  vobSubParam subparam={NULL,0,0};
  char *srtFileName=NULL;
  char *glyphFileName=NULL;
  char *tsFileName=NULL;
  admGlyph head(16,16);
  char *globalGlyph=NULL;
  uint32_t globalGlyphOn=0;
  uint32_t pid=0x96;
  ADM_OCR_SOURCE source;
  
  memset(&source,0,sizeof(source));
  source.type=ADM_OCR_TYPE_TS;
  
  prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&globalGlyphOn);
  if(globalGlyphOn)
  {
     prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyph);
     if(!*globalGlyph)
     {
        ADM_dezalloc(globalGlyph);
        globalGlyph=NULL; 
     }
  }

  if(globalGlyph)
  {
    glyphFileName=globalGlyph;
  }
_againX:  
  // Fist build a dialogFactory to get input and output files
  diaElemFile     selectTs(1,&tsFileName,QT_TR_NOOP("Input TS:"), NULL, QT_TR_NOOP("Select TS file"));
  diaElemUInteger selectPid(&pid,QT_TR_NOOP("Subtitle PID:"),0,255);
  diaElemFile     selectGlyph(1,&glyphFileName,QT_TR_NOOP("Use glyphset (optional):"), NULL, QT_TR_NOOP("Select GlyphSet file"));  
  diaElemFile     selectSrt(1,&srtFileName,QT_TR_NOOP("Output SRT file"), NULL, QT_TR_NOOP("Save SRT file"));
  
  diaElem *elems[]={&selectTs,&selectPid,&selectSrt,&selectGlyph};
  
  
   uint32_t n=4;
   if(globalGlyph)
   {
     n--; // Remove glyph from dialog
   }
  
        if( !diaFactoryRun(QT_TR_NOOP("Select input and ouput files"),n,elems))
        {
          cleanupSub(&source);
          if(srtFileName )ADM_dezalloc(srtFileName);
          srtFileName=NULL;
          destroyGlyphTree(&head);
          return 0;
        }
        // TS file exists ?
        if(!ADM_fileExist(tsFileName))
        {
        	  GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid TS file."));
        	  goto _againX;
        }
       
        if(!srtFileName || !*srtFileName)
        {
          GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid output SRT file."));
          goto _againX; 
        }
         if(glyphFileName && *glyphFileName)
         {
           if(!ADM_fileExist(glyphFileName))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist."));
              goto _againX; 
            }
            // Purge previous glyph set if any
            destroyGlyphTree(&head);
            uint32_t nb;
            printf("[OCR] Loading glyphset :<%s>\n",glyphFileName);
            if(!loadGlyph(glyphFileName,&head,&nb))
            {
              GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Cannot load the glyphset file."));
              goto _againX;               
            }
            printf("[GLYPH] Found %u glyph\n");
         }
        // We have our SRT and our TS file
        // Call the OCR engine...
         source.TsFile=ADM_strdup(tsFileName);
         source.TsPid=pid;
         ADM_ocr_engine(source,srtFileName,&head);
        
        // Save glyph set 

        if(globalGlyph)
        {
          uint32_t nb=1;
           saveGlyph(globalGlyph,&head,nb);
        }else
        {
            char *save=NULL;
            uint32_t nb=1;
              diaElemFile     selectSave(1,&save,QT_TR_NOOP("GlyphSet filename"), NULL, QT_TR_NOOP("Save GlyphSet file"));
              diaElem *elems2[]={&selectSave};
            if( diaFactoryRun(QT_TR_NOOP("Save GlyphSet"),1,elems2))
            {
              saveGlyph(save,&head,nb);
            }
            if(save) ADM_dezalloc(save);
        }

  cleanupSub(&source);
  if(srtFileName )ADM_dezalloc(srtFileName);
  srtFileName=NULL;
  
  if(tsFileName )ADM_dezalloc(tsFileName);
  tsFileName=NULL;
  
  destroyGlyphTree(&head);
  return 1;  
}
/******************************************************************************************
 Setup (input/output files etc..)
*****************************************************************************************/
ReplyType setup(void)
{
int sel;
char text[1024];
    while(1)
    {
    //gtk_widget_set_sensitive(WID(buttonAccept),0);
    //gtk_widget_set_sensitive(WID(buttonSkip),0);
    //gtk_widget_set_sensitive(WID(entryEntry),0);
    GTK_PURGE;   
    // Main loop : Only accept glyph load/save
    // Sub & srt select & start ocr
    gtk_widget_set_sensitive(WID(frameGlyph),1);
    gtk_widget_set_sensitive(WID(frameLoad),1);
    gtk_widget_set_sensitive(WID(buttonStart),1);
    
    gtk_widget_set_sensitive(WID(frameBitmap),0);
    //gtk_widget_set_sensitive(WID(Current_Glyph),0); 
     switch(sel=gtk_dialog_run(GTK_DIALOG(dialog)))
     {
        case actionLoadVob:
                {
                   
                        subparam.index=lang_index;
                        subparam.subname=NULL;
                        if(DIA_vobsub(&subparam))
                        {
                            lang_index=subparam.index;
                            gtk_label_set_text(GTK_LABEL(WID(labelVobsub)),subparam.subname);
                        }
                        
                    
                }
                break;
        case actionSaveSub:
                {
                    char *srt=NULL;
                    GUI_FileSelWrite(_("Select SRT to save"), &srt);
                    if(srt)
                    {
                        gtk_label_set_text(GTK_LABEL(WID(labelSrt)),srt);
                    }
                }
                break;
        
        case actionLoadGlyph:
            {
                 char *gly=NULL;
                    
                    GUI_FileSelRead(_("Select Glyoh to save"), &gly);
                    if(gly)
                    {
                            loadGlyph(gly);
                            sprintf(text,"%03d",nbGlyphs);
                            gtk_label_set_text(GTK_LABEL(WID(labelNbGlyphs)),text);
                    }
            }
                break;
        
        case actionSaveGlyph:
            
                    if(!nbGlyphs)
                    {
                      GUI_Error_HIG(_("No glyphs to save"), NULL);
                        break;
                    }                  
                    saveGlyph();                                      
                    break;
        
        case GTK_RESPONSE_CLOSE: 
            printf("Close req\n");
            return ReplyClose;
        default:
            printf("Other input:%d\n",sel);
     }
    // Everything selected, check
    if(sel==actionGo) return ReplyOk;
    }
}