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); }
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 }