static void
WriteDumpFile(FILE* aDumpFile, AudioStream* aStream, PRUint32 aFrames,
              void* aBuffer)
{
  if (!aDumpFile)
    return;

  PRUint32 samples = aStream->GetChannels()*aFrames;
  if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
    fwrite(aBuffer, 2, samples, aDumpFile);
    return;
  }

  NS_ASSERTION(AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_FLOAT32, "bad format");
  nsAutoTArray<PRUint8, 1024*2> buf;
  buf.SetLength(samples*2);
  float* input = static_cast<float*>(aBuffer);
  PRUint8* output = buf.Elements();
  for (PRUint32 i = 0; i < samples; ++i) {
    SetUint16LE(output + i*2, PRInt16(input[i]*32767.0f));
  }
  fwrite(output, 2, samples, aDumpFile);
  fflush(aDumpFile);
}
Beispiel #2
0
void
gfxDWriteFont::ComputeMetrics()
{
    DWRITE_FONT_METRICS fontMetrics;
    mFontFace->GetMetrics(&fontMetrics);

    if (mStyle.sizeAdjust != 0.0) {
        gfxFloat aspect = (gfxFloat)fontMetrics.xHeight /
                   fontMetrics.designUnitsPerEm;
        mAdjustedSize = mStyle.GetAdjustedSize(aspect);
    } else {
        mAdjustedSize = mStyle.size;
    }

    mMetrics.xHeight =
        ((gfxFloat)fontMetrics.xHeight /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;

    mMetrics.maxAscent = 
        ceil(((gfxFloat)fontMetrics.ascent /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.maxDescent = 
        ceil(((gfxFloat)fontMetrics.descent /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.maxHeight = mMetrics.maxAscent + mMetrics.maxDescent;

    mMetrics.emHeight = mAdjustedSize;
    mMetrics.emAscent = mMetrics.emHeight *
        mMetrics.maxAscent / mMetrics.maxHeight;
    mMetrics.emDescent = mMetrics.emHeight - mMetrics.emAscent;

    mMetrics.maxAdvance = mAdjustedSize;

    // try to get the true maxAdvance value from 'hhea'
    PRUint8 *tableData;
    PRUint32 len;
    void *tableContext = NULL;
    BOOL exists;
    HRESULT hr =
        mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('h', 'h', 'e', 'a'),
                                   (const void**)&tableData,
                                   &len,
                                   &tableContext,
                                   &exists);
    if (SUCCEEDED(hr)) {
        if (exists && len >= sizeof(mozilla::HheaTable)) {
            const mozilla::HheaTable* hhea =
                reinterpret_cast<const mozilla::HheaTable*>(tableData);
            mMetrics.maxAdvance = ((gfxFloat)PRUint16(hhea->advanceWidthMax) /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
        mFontFace->ReleaseFontTable(tableContext);
    }

    mMetrics.internalLeading = 
        ceil(((gfxFloat)(fontMetrics.ascent + 
                    fontMetrics.descent - 
                    fontMetrics.designUnitsPerEm) / 
                    fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.externalLeading = 
        ceil(((gfxFloat)fontMetrics.lineGap /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);

    UINT16 glyph = (PRUint16)GetSpaceGlyph();
    DWRITE_GLYPH_METRICS metrics;
    mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics);
    mMetrics.spaceWidth = 
        ((gfxFloat)metrics.advanceWidth /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;

    // try to get aveCharWidth from the OS/2 table, fall back to measuring 'x'
    // if the table is not available
    mMetrics.aveCharWidth = 0;
    hr = mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('O', 'S', '/', '2'),
                                    (const void**)&tableData,
                                    &len,
                                    &tableContext,
                                    &exists);
    if (SUCCEEDED(hr)) {
        if (exists && len >= 4) {
            // Not checking against sizeof(mozilla::OS2Table) here because older
            // versions of the table have different sizes; we only need the first
            // two 16-bit fields here.
            const mozilla::OS2Table* os2 =
                reinterpret_cast<const mozilla::OS2Table*>(tableData);
            mMetrics.aveCharWidth = ((gfxFloat)PRInt16(os2->xAvgCharWidth) /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
        mFontFace->ReleaseFontTable(tableContext);
    }

    UINT32 ucs;
    if (mMetrics.aveCharWidth < 1) {
        ucs = L'x';
        if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
            SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {    
            mMetrics.aveCharWidth = 
                ((gfxFloat)metrics.advanceWidth /
                           fontMetrics.designUnitsPerEm) * mAdjustedSize;
        } else {
            // Let's just assume the X is square.
            mMetrics.aveCharWidth = 
                ((gfxFloat)fontMetrics.xHeight /
                           fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
    }

    ucs = L'0';
    if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
        SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
        mMetrics.zeroOrAveCharWidth = 
            ((gfxFloat)metrics.advanceWidth /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
    } else {
        mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
    }

    mMetrics.underlineOffset = 
        ((gfxFloat)fontMetrics.underlinePosition /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.underlineSize = 
        ((gfxFloat)fontMetrics.underlineThickness /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.strikeoutOffset = 
        ((gfxFloat)fontMetrics.strikethroughPosition /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.strikeoutSize = 
        ((gfxFloat)fontMetrics.strikethroughThickness /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.superscriptOffset = 0;
    mMetrics.subscriptOffset = 0;

    mFUnitsConvFactor = GetAdjustedSize() / fontMetrics.designUnitsPerEm;

    SanitizeMetrics(&mMetrics, GetFontEntry()->mIsBadUnderlineFont);

#if 0
    printf("Font: %p (%s) size: %f\n", this,
           NS_ConvertUTF16toUTF8(GetName()).get(), mStyle.size);
    printf("    emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
    printf("    maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
    printf("    internalLeading: %f externalLeading: %f\n", mMetrics.internalLeading, mMetrics.externalLeading);
    printf("    spaceWidth: %f aveCharWidth: %f zeroOrAve: %f xHeight: %f\n",
           mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.zeroOrAveCharWidth, mMetrics.xHeight);
    printf("    uOff: %f uSize: %f stOff: %f stSize: %f supOff: %f subOff: %f\n",
           mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize,
           mMetrics.superscriptOffset, mMetrics.subscriptOffset);
#endif
}