将truetype字体默认转换为NV路径中的像素大小

时间:2013-04-30 13:59:34

标签: opengl fonts true-type-fonts freetype

我正在使用NVidia Path extension(NV路径)为OpenGL引擎编写文本模块。该扩展程序允许使用trutype metrics加载系统和外部字体文件。现在,我需要能够在渲染文本时为字形设置标准字体大小(以像素为单位)。默认情况下,加载的字形有EMscale = 2048.搜索字形指标到像素的转换我发现了这个:

  

将FUnits转换为像素

     

em方块中的值将转换为像素中的值   通过将它们乘以比例来协调系统。这个规模是:   pointSize * resolution /(每英寸72点* units_per_em)

所以units_per_em等于2048,pointSize和resolution是我无法解决的未知数。如何获得视口宽度和高度的分辨率值进入这个等式?另外,如果我的输入是字体的像素大小,那么点大小应该是多少?

我尝试使用不同类型的输入来解决这个等式,但我的渲染文本总是比参考文本(AfterEffects)更小(或更大)。

NV_Path文档引用FreeType2 metrics。参考文献说:

  

在face-> glyph->指标中找到的指标通常用。表示   26.6像素格式(即1/64像素),除非在调用FT_Load_Glyph或FT_Load_Char时使用FT_LOAD_NO_SCALE标志。在   在这种情况下,指标将以原始字体单位表示。

我试图将文本模型矩阵缩小1/64。它接近正确的尺寸,但仍然不完美。

以下是我目前在代码中设置文本呈现的方法:

            emScale=2048;

        glyphBase = glGenPathsNV(1+numChars);
    pathTemplate= ~0;
    glPathGlyphRangeNV(glyphBase,GL_SYSTEM_FONT_NAME_NV,
        "Verdana",GL_BOLD_BIT_NV,0,numChars,GL_SKIP_MISSING_GLYPH_NV,pathTemplate,emScale);


    /* Query font and glyph metrics. */
    glGetPathMetricRangeNV(
        GL_FONT_Y_MIN_BOUNDS_BIT_NV|
        GL_FONT_Y_MAX_BOUNDS_BIT_NV|
        GL_FONT_X_MIN_BOUNDS_BIT_NV|
        GL_FONT_X_MAX_BOUNDS_BIT_NV|
        GL_FONT_UNDERLINE_POSITION_BIT_NV|
        GL_FONT_UNDERLINE_THICKNESS_BIT_NV,glyphBase+' ' ,1 ,6*sizeof(GLfloat),font_data);


    glGetPathMetricRangeNV(GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV,
        glyphBase,numChars,0,horizontalAdvance);

    /* Query spacing information for example's message. */

    messageLen = strlen(message);
    xtranslate =(GLfloat*)malloc(sizeof(GLfloat) *messageLen);
    if(!xtranslate){
        fprintf(stderr, "%s: malloc of xtranslate failed\n", "Text3D error");
        exit(1);
    }

    xtranslate[0] = 0.0f;  /* Initial xtranslate is zero. */
    /* Use 100% spacing; use 0.9 for both for 90% spacing. */
    GLfloat advanceScale = 1.0f,
        kerningScale = 1.0f; 

    glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV,
        (GLsizei)messageLen,GL_UNSIGNED_BYTE,message,glyphBase,
        advanceScale,kerningScale,GL_TRANSLATE_X_NV,&xtranslate[1]); /* messageLen-1 accumulated translates are written here. */

    const unsigned char *message_ub = (const unsigned char*)message;
    totalAdvance = xtranslate[messageLen-1] +
        horizontalAdvance[message_ub[messageLen-1]];
    xBorder = totalAdvance / messageLen;

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_NOTEQUAL ,0 ,~0);
    glStencilOp(GL_KEEP,GL_KEEP,GL_ZERO);


    ////////// init matrices  /////////////

    translate(model ,vec3(0));
    translate(view  ,vec3(0));

                    float nearF=1 ,farF = 1200;
            glViewport(0,0,_viewPortW,_viewPortH);
        glMatrixLoadIdentityEXT(GL_PROJECTION);


        float aspect_ratio =(float) _viewPortW /(float) _viewPortH;
        glMatrixFrustumEXT(GL_PROJECTION ,-aspect_ratio,aspect_ratio,-1 ,1 ,nearF,farF);





        model=translate(model,vec3(0.0f,384.0,0.0f));//move up
            //scale by 26.6 also doesn't work:
    model=scale(model,vec3((1.0f/26.6f),1.0f/26.6f,1.0f/26.6f));
    view=lookAt(vec3(0,0,0),vec3(0,0,-1),vec3(0,1,0));

}

1 个答案:

答案 0 :(得分:0)

分辨率取决于设备,使用的公式为DPI(每英寸点数)。 point_size是字体的大小,由用户在Points中选择。 A Point = 1/72英寸(实际上这是PostScript中使用的Point的大小,实际单位" Point"排版机使用的略有不同)。

可以使用OS相关方法查询设备分辨率。 Google for"显示DPI $ NAMEOFOPERATINGSYSTEM"。使用点大小可以为您提供与所用显示设备无关的恒定物理字体大小。

请注意,使用OpenGL渲染时,您仍然需要通过必须考虑的转换管道。