mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
Issue #1751 -- Remove XP_MACOSX conditionals and support files from /gfx
This commit is contained in:
parent
9aed800398
commit
ccf9e5f54b
40 changed files with 16 additions and 4790 deletions
|
|
@ -260,15 +260,6 @@ Factory::CheckSurfaceSize(const IntSize &sz,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// CoreGraphics is limited to images < 32K in *height*,
|
||||
// so clamp all surfaces on the Mac to that height
|
||||
if (sz.height > SHRT_MAX) {
|
||||
gfxDebug() << "Surface size too large (exceeds CoreGraphics limit)!";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// assuming 4 bytes per pixel, make sure the allocation size
|
||||
// doesn't overflow a int32_t either
|
||||
CheckedInt<int32_t> stride = GetAlignedStride<16>(sz.width, 4);
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@ public:
|
|||
// XXX - temporarily disabled, see bug 1209039
|
||||
//
|
||||
// // Call this from the thread itself because of Mac.
|
||||
//#ifdef XP_MACOSX
|
||||
// pthread_setname_np(aName);
|
||||
//#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
//#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
// pthread_set_name_np(mThread, aName);
|
||||
//#elif defined(__NetBSD__)
|
||||
// pthread_setname_np(mThread, "%s", (void*)aName);
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@
|
|||
#include "Logging.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
|
|
@ -61,9 +57,6 @@ struct NameRecord
|
|||
enum ENameDecoder : int
|
||||
{
|
||||
eNameDecoderUTF16,
|
||||
#if defined(XP_MACOSX)
|
||||
eNameDecoderMacRoman,
|
||||
#endif
|
||||
eNameDecoderNone
|
||||
};
|
||||
|
||||
|
|
@ -128,19 +121,6 @@ IsUTF16Encoding(const NameRecord *aNameRecord)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
static bool
|
||||
IsMacRomanEncoding(const NameRecord *aNameRecord)
|
||||
{
|
||||
if (aNameRecord->platformID == PLATFORM_ID_MAC &&
|
||||
aNameRecord->encodingID == ENCODING_ID_MAC_ROMAN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static NameRecordMatchers*
|
||||
CreateCanonicalMatchers(const BigEndianUint16& aNameID)
|
||||
{
|
||||
|
|
@ -149,37 +129,6 @@ CreateCanonicalMatchers(const BigEndianUint16& aNameID)
|
|||
// records and Mac platform records.
|
||||
NameRecordMatchers *matchers = new NameRecordMatchers();
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// First, look for the English name.
|
||||
if (!matchers->append(
|
||||
[=](const NameRecord *aNameRecord) {
|
||||
if (aNameRecord->nameID == aNameID &&
|
||||
aNameRecord->languageID == LANG_ID_MAC_ENGLISH &&
|
||||
aNameRecord->platformID == PLATFORM_ID_MAC &&
|
||||
IsMacRomanEncoding(aNameRecord)) {
|
||||
return eNameDecoderMacRoman;
|
||||
} else {
|
||||
return eNameDecoderNone;
|
||||
}
|
||||
})) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
// Second, look for all languages.
|
||||
if (!matchers->append(
|
||||
[=](const NameRecord *aNameRecord) {
|
||||
if (aNameRecord->nameID == aNameID &&
|
||||
aNameRecord->platformID == PLATFORM_ID_MAC &&
|
||||
IsMacRomanEncoding(aNameRecord)) {
|
||||
return eNameDecoderMacRoman;
|
||||
} else {
|
||||
return eNameDecoderNone;
|
||||
}
|
||||
})) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#endif /* defined(XP_MACOSX) */
|
||||
|
||||
// First, look for the English name (this will normally succeed).
|
||||
if (!matchers->append(
|
||||
[=](const NameRecord *aNameRecord) {
|
||||
|
|
@ -273,10 +222,6 @@ SFNTNameTable::ReadU16Name(const NameRecordMatchers& aMatchers,
|
|||
switch (aMatchers[i](record)) {
|
||||
case eNameDecoderUTF16:
|
||||
return ReadU16NameFromU16Record(record, aU16Name);
|
||||
#if defined(XP_MACOSX)
|
||||
case eNameDecoderMacRoman:
|
||||
return ReadU16NameFromMacRomanRecord(record, aU16Name);
|
||||
#endif
|
||||
case eNameDecoderNone:
|
||||
break;
|
||||
default:
|
||||
|
|
@ -311,46 +256,5 @@ SFNTNameTable::ReadU16NameFromU16Record(const NameRecord *aNameRecord,
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
bool
|
||||
SFNTNameTable::ReadU16NameFromMacRomanRecord(const NameRecord *aNameRecord,
|
||||
mozilla::u16string& aU16Name)
|
||||
{
|
||||
uint32_t offset = aNameRecord->offset;
|
||||
uint32_t length = aNameRecord->length;
|
||||
if (mStringDataLength < offset + length) {
|
||||
gfxWarning() << "Name data too short to contain name string.";
|
||||
return false;
|
||||
}
|
||||
if (length > INT_MAX) {
|
||||
gfxWarning() << "Name record too long to decode.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// pointer to the Mac Roman encoded string in the name record
|
||||
const uint8_t *encodedStr = mStringData + offset;
|
||||
|
||||
CFStringRef cfString;
|
||||
cfString = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, encodedStr,
|
||||
length, kCFStringEncodingMacRoman,
|
||||
false, kCFAllocatorNull);
|
||||
|
||||
// length (in UTF-16 code pairs) of the decoded string
|
||||
CFIndex decodedLength = CFStringGetLength(cfString);
|
||||
|
||||
// temporary buffer
|
||||
UniquePtr<UniChar[]> u16Buffer = MakeUnique<UniChar[]>(decodedLength);
|
||||
|
||||
CFStringGetCharacters(cfString, CFRangeMake(0, decodedLength),
|
||||
u16Buffer.get());
|
||||
|
||||
CFRelease(cfString);
|
||||
|
||||
aU16Name.assign(reinterpret_cast<char16_t*>(u16Buffer.get()), decodedLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
||||
|
|
|
|||
|
|
@ -55,11 +55,6 @@ private:
|
|||
bool ReadU16NameFromU16Record(const NameRecord *aNameRecord,
|
||||
mozilla::u16string& aU16Name);
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
bool ReadU16NameFromMacRomanRecord(const NameRecord *aNameRecord,
|
||||
mozilla::u16string& aU16Name);
|
||||
#endif
|
||||
|
||||
const NameRecord *mFirstRecord;
|
||||
const NameRecord *mEndOfRecords;
|
||||
const uint8_t *mStringData;
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@
|
|||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "MacIOSurfaceImage.h"
|
||||
#include "GLContextCGL.h"
|
||||
#endif
|
||||
|
||||
using mozilla::layers::PlanarYCbCrImage;
|
||||
using mozilla::layers::PlanarYCbCrData;
|
||||
|
||||
|
|
@ -186,34 +181,6 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
|||
} \n\
|
||||
";
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
const char kTexNV12PlanarBlit_FragShaderSource[] = "\
|
||||
#version 100 \n\
|
||||
#extension GL_ARB_texture_rectangle : require \n\
|
||||
#ifdef GL_ES \n\
|
||||
precision mediump float \n\
|
||||
#endif \n\
|
||||
varying vec2 vTexCoord; \n\
|
||||
uniform sampler2DRect uYTexture; \n\
|
||||
uniform sampler2DRect uCbCrTexture; \n\
|
||||
uniform vec2 uYTexScale; \n\
|
||||
uniform vec2 uCbCrTexScale; \n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
float y = texture2DRect(uYTexture, vTexCoord * uYTexScale).r; \n\
|
||||
float cb = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).r; \n\
|
||||
float cr = texture2DRect(uCbCrTexture, vTexCoord * uCbCrTexScale).a; \n\
|
||||
y = (y - 0.06275) * 1.16438; \n\
|
||||
cb = cb - 0.50196; \n\
|
||||
cr = cr - 0.50196; \n\
|
||||
gl_FragColor.r = y + cr * 1.59603; \n\
|
||||
gl_FragColor.g = y - 0.81297 * cr - 0.39176 * cb; \n\
|
||||
gl_FragColor.b = y + cb * 2.01723; \n\
|
||||
gl_FragColor.a = 1.0; \n\
|
||||
} \n\
|
||||
";
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
|
||||
GLuint* programPtr;
|
||||
|
|
@ -236,13 +203,6 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
|||
fragShaderPtr = &mTexYUVPlanarBlit_FragShader;
|
||||
fragShaderSource = kTexYUVPlanarBlit_FragShaderSource;
|
||||
break;
|
||||
#ifdef XP_MACOSX
|
||||
case ConvertMacIOSurfaceImage:
|
||||
programPtr = &mTexNV12PlanarBlit_Program;
|
||||
fragShaderPtr = &mTexNV12PlanarBlit_FragShader;
|
||||
fragShaderSource = kTexNV12PlanarBlit_FragShaderSource;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -393,24 +353,6 @@ GLBlitHelper::InitTexQuadProgram(BlitType target)
|
|||
mGL->fUniform1i(texCr, Channel_Cr);
|
||||
break;
|
||||
}
|
||||
case ConvertMacIOSurfaceImage: {
|
||||
#ifdef XP_MACOSX
|
||||
GLint texY = mGL->fGetUniformLocation(program, "uYTexture");
|
||||
GLint texCbCr = mGL->fGetUniformLocation(program, "uCbCrTexture");
|
||||
mYTexScaleLoc = mGL->fGetUniformLocation(program, "uYTexScale");
|
||||
mCbCrTexScaleLoc= mGL->fGetUniformLocation(program, "uCbCrTexScale");
|
||||
|
||||
DebugOnly<bool> hasUniformLocations = texY != -1 &&
|
||||
texCbCr != -1 &&
|
||||
mYTexScaleLoc != -1 &&
|
||||
mCbCrTexScaleLoc != -1;
|
||||
MOZ_ASSERT(hasUniformLocations, "uniforms not found");
|
||||
|
||||
mGL->fUniform1i(texY, Channel_Y);
|
||||
mGL->fUniform1i(texCbCr, Channel_Cb);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -678,47 +620,6 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
bool
|
||||
GLBlitHelper::BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage)
|
||||
{
|
||||
ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
|
||||
MacIOSurface* surf = ioImage->GetSurface();
|
||||
|
||||
GLint oldTex[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
|
||||
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex[i]);
|
||||
}
|
||||
|
||||
GLuint textures[2];
|
||||
mGL->fGenTextures(2, textures);
|
||||
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[0]);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 0);
|
||||
mGL->fUniform2f(mYTexScaleLoc, surf->GetWidth(0), surf->GetHeight(0));
|
||||
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE1);
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textures[1]);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
surf->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL)->GetCGLContext(), 1);
|
||||
mGL->fUniform2f(mCbCrTexScaleLoc, surf->GetWidth(1), surf->GetHeight(1));
|
||||
|
||||
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
|
||||
mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]);
|
||||
}
|
||||
|
||||
mGL->fDeleteTextures(2, textures);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
||||
const gfx::IntSize& destSize,
|
||||
|
|
@ -736,13 +637,6 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
|||
srcOrigin = OriginPos::BottomLeft;
|
||||
break;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case ImageFormat::MAC_IOSURFACE:
|
||||
type = ConvertMacIOSurfaceImage;
|
||||
srcOrigin = OriginPos::TopLeft;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -768,11 +662,6 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case ConvertMacIOSurfaceImage:
|
||||
return BlitMacIOSurfaceImage(srcImage->AsMacIOSurfaceImage());
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,9 +107,6 @@ class GLBlitHelper final
|
|||
void BindAndUploadEGLImage(EGLImage image, GLuint target);
|
||||
|
||||
bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage);
|
||||
#ifdef XP_MACOSX
|
||||
bool BlitMacIOSurfaceImage(layers::MacIOSurfaceImage* ioImage);
|
||||
#endif
|
||||
|
||||
explicit GLBlitHelper(GLContext* gl);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@
|
|||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
#include "nsCocoaFeatures.h"
|
||||
#endif
|
||||
|
|
@ -877,18 +873,6 @@ GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
|
|||
// multisampling hardcodes blending with the default blendfunc, which breaks WebGL.
|
||||
MarkUnsupported(GLFeature::framebuffer_multisample);
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// The Mac Nvidia driver, for versions up to and including 10.8,
|
||||
// don't seem to properly support this. See 814839
|
||||
// this has been fixed in Mac OS X 10.9. See 907946
|
||||
// and it also works in 10.8.3 and higher. See 1094338.
|
||||
if (Vendor() == gl::GLVendor::NVIDIA &&
|
||||
!nsCocoaFeatures::IsAtLeastVersion(10,8,3))
|
||||
{
|
||||
MarkUnsupported(GLFeature::depth_texture);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) {
|
||||
|
|
@ -1009,25 +993,6 @@ GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
|
|||
raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize);
|
||||
raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mWorkAroundDriverBugs) {
|
||||
if (mVendor == GLVendor::Intel) {
|
||||
// see bug 737182 for 2D textures, bug 684882 for cube map textures.
|
||||
mMaxTextureSize = std::min(mMaxTextureSize, 4096);
|
||||
mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 512);
|
||||
// for good measure, we align renderbuffers on what we do for 2D textures
|
||||
mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096);
|
||||
mNeedsTextureSizeChecks = true;
|
||||
} else if (mVendor == GLVendor::NVIDIA) {
|
||||
// See bug 879656. 8192 fails, 8191 works.
|
||||
mMaxTextureSize = std::min(mMaxTextureSize, 8191);
|
||||
mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191);
|
||||
|
||||
// Part of the bug 879656, but it also doesn't hurt the 877949
|
||||
mNeedsTextureSizeChecks = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_X11
|
||||
if (mWorkAroundDriverBugs) {
|
||||
if (mVendor == GLVendor::Nouveau) {
|
||||
|
|
@ -1800,20 +1765,6 @@ GLContext::InitExtensions()
|
|||
MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
|
||||
MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Bug 1009642: On OSX Mavericks (10.9), the driver for Intel HD
|
||||
// 3000 appears to be buggy WRT updating sub-images of S3TC
|
||||
// textures with glCompressedTexSubImage2D. Works on Intel HD 4000
|
||||
// and Intel HD 5000/Iris that I tested.
|
||||
// Bug 1124996: Appears to be the same on OSX Yosemite (10.10)
|
||||
if (nsCocoaFeatures::macOSVersionMajor() == 10 &&
|
||||
nsCocoaFeatures::macOSVersionMinor() >= 9 &&
|
||||
Renderer() == GLRenderer::IntelHD3000)
|
||||
{
|
||||
MarkExtensionUnsupported(EXT_texture_compression_s3tc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (shouldDumpExts) {
|
||||
|
|
@ -2828,35 +2779,6 @@ GLContext::fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum f
|
|||
}
|
||||
|
||||
AfterGLReadCall();
|
||||
|
||||
// Check if GL is giving back 1.0 alpha for
|
||||
// RGBA reads to RGBA images from no-alpha buffers.
|
||||
#ifdef XP_MACOSX
|
||||
if (WorkAroundDriverBugs() &&
|
||||
Vendor() == gl::GLVendor::NVIDIA &&
|
||||
format == LOCAL_GL_RGBA &&
|
||||
type == LOCAL_GL_UNSIGNED_BYTE &&
|
||||
!IsCoreProfile() &&
|
||||
width && height)
|
||||
{
|
||||
GLint alphaBits = 0;
|
||||
fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
|
||||
if (!alphaBits) {
|
||||
const uint32_t alphaMask = 0xff000000;
|
||||
|
||||
uint32_t* itr = (uint32_t*)pixels;
|
||||
uint32_t testPixel = *itr;
|
||||
if ((testPixel & alphaMask) != alphaMask) {
|
||||
// We need to set the alpha channel to 1.0 manually.
|
||||
uint32_t* itrEnd = itr + width*height; // Stride is guaranteed to be width*4.
|
||||
|
||||
for (; itr != itrEnd; itr++) {
|
||||
*itr |= alphaMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -34,13 +34,6 @@ namespace gl {
|
|||
#define DEFAULT_IMPL WGL
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderCGL
|
||||
#include "GLContextProviderImpl.h"
|
||||
#undef GL_CONTEXT_PROVIDER_NAME
|
||||
#define GL_CONTEXT_PROVIDER_DEFAULT GLContextProviderCGL
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
#define GL_CONTEXT_PROVIDER_NAME GLContextProviderGLX
|
||||
#include "GLContextProviderImpl.h"
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@
|
|||
#include "mozilla/gfx/DeviceManagerDx.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "SharedSurfaceIO.h"
|
||||
#endif
|
||||
|
||||
#ifdef GL_PROVIDER_GLX
|
||||
#include "GLXLibrary.h"
|
||||
#include "SharedSurfaceGLX.h"
|
||||
|
|
@ -84,9 +80,7 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
|
|||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (backend) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
#if defined(XP_MACOSX)
|
||||
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
|
||||
#elif defined(GL_PROVIDER_GLX)
|
||||
#if defined(GL_PROVIDER_GLX)
|
||||
if (sGLXLibrary.UseTextureFromPixmap())
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
#elif defined(MOZ_WIDGET_UIKIT)
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "mozilla/gfx/QuartzSupport.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include <d3d10_1.h>
|
||||
|
|
|
|||
|
|
@ -166,9 +166,6 @@ protected:
|
|||
class GLImage;
|
||||
class EGLImageImage;
|
||||
class SharedRGBImage;
|
||||
#if defined(XP_MACOSX)
|
||||
class MacIOSurfaceImage;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A class representing a buffer of pixel data. The data can be in one
|
||||
|
|
@ -223,9 +220,6 @@ public:
|
|||
/* Access to derived classes. */
|
||||
virtual EGLImageImage* AsEGLImageImage() { return nullptr; }
|
||||
virtual GLImage* AsGLImage() { return nullptr; }
|
||||
#ifdef XP_MACOSX
|
||||
virtual MacIOSurfaceImage* AsMacIOSurfaceImage() { return nullptr; }
|
||||
#endif
|
||||
virtual PlanarYCbCrImage* AsPlanarYCbCrImage() { return nullptr; }
|
||||
|
||||
virtual NVImage* AsNVImage() { return nullptr; }
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TextureHostBasic.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include "MacIOSurfaceTextureHostBasic.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::gfx;
|
||||
|
|
@ -19,13 +16,6 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
|
|||
ISurfaceAllocator* aDeallocator,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
if (aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorMacIOSurface) {
|
||||
const SurfaceDescriptorMacIOSurface& desc =
|
||||
aDesc.get_SurfaceDescriptorMacIOSurface();
|
||||
return MakeAndAddRef<MacIOSurfaceTextureHostBasic>(aFlags, desc);
|
||||
}
|
||||
#endif
|
||||
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,10 +48,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "mozilla/layers/MacIOSurfaceTextureClientOGL.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
|
||||
#else
|
||||
|
|
@ -1075,12 +1071,6 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!data && gfxPrefs::UseIOSurfaceTextures()) {
|
||||
data = MacIOSurfaceTextureData::Create(aSize, aFormat, moz2DBackend);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
#include "UnitTransforms.h" // for ViewAs
|
||||
#include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
#ifdef XP_MACOSX
|
||||
#include "gfxPlatformMac.h"
|
||||
#endif
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
#include "gfxUtils.h" // for frame color util
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
|
|
@ -881,9 +878,6 @@ LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegi
|
|||
}
|
||||
|
||||
mozilla::widget::WidgetRenderingContext widgetContext;
|
||||
#if defined(XP_MACOSX)
|
||||
widgetContext.mLayerManager = this;
|
||||
#endif
|
||||
|
||||
{
|
||||
PROFILER_LABEL("LayerManagerComposite", "PreRender",
|
||||
|
|
|
|||
|
|
@ -39,10 +39,6 @@
|
|||
#include "mozilla/layers/X11TextureHost.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "../opengl/MacIOSurfaceTextureHostOGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/layers/TextureDIB.h"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
@ -13,10 +11,6 @@
|
|||
#include "SurfaceTypes.h"
|
||||
#include "mozilla/WidgetUtils.h"
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
# include "mozilla/layers/ShadowLayerUtilsX11.h"
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@
|
|||
#include "GLBlitTextureImageHelper.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
|
|
@ -49,15 +45,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
|
||||
const SurfaceDescriptorMacIOSurface& desc =
|
||||
aDesc.get_SurfaceDescriptorMacIOSurface();
|
||||
result = new MacIOSurfaceTextureHostOGL(aFlags, desc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
|
||||
const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
|
||||
result = new GLTextureHost(aFlags, desc.texture(),
|
||||
|
|
|
|||
|
|
@ -239,11 +239,7 @@ nsDeviceContext::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
|
|||
bool
|
||||
nsDeviceContext::IsPrinterContext()
|
||||
{
|
||||
return mPrintTarget != nullptr
|
||||
#ifdef XP_MACOSX
|
||||
|| mCachedPrintTarget != nullptr
|
||||
#endif
|
||||
;
|
||||
return mPrintTarget != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -347,17 +343,6 @@ nsDeviceContext::CreateRenderingContextCommon(bool aWantReferenceContext)
|
|||
MOZ_ASSERT(mWidth > 0 && mHeight > 0);
|
||||
|
||||
RefPtr<PrintTarget> printingTarget = mPrintTarget;
|
||||
#ifdef XP_MACOSX
|
||||
// CreateRenderingContext() can be called (on reflow) after EndPage()
|
||||
// but before BeginPage(). On OS X (and only there) mPrintTarget
|
||||
// will in this case be null, because OS X printing surfaces are
|
||||
// per-page, and therefore only truly valid between calls to BeginPage()
|
||||
// and EndPage(). But we can get away with fudging things here, if need
|
||||
// be, by using a cached copy.
|
||||
if (!printingTarget) {
|
||||
printingTarget = mCachedPrintTarget;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This will usually be null, depending on the pref print.print_via_parent.
|
||||
RefPtr<DrawEventRecorder> recorder;
|
||||
|
|
@ -378,9 +363,6 @@ nsDeviceContext::CreateRenderingContextCommon(bool aWantReferenceContext)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
|
||||
#endif
|
||||
dt->AddUserData(&sDisablePixelSnapping, (void*)0x1, nullptr);
|
||||
|
||||
RefPtr<gfxContext> pContext = gfxContext::CreateOrNull(dt);
|
||||
|
|
@ -543,12 +525,6 @@ nsDeviceContext::BeginPage(void)
|
|||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// We need to get a new surface for each page on the Mac, as the
|
||||
// CGContextRefs are only good for one page.
|
||||
mPrintTarget = mDeviceContextSpec->MakePrintTarget();
|
||||
#endif
|
||||
|
||||
rv = mPrintTarget->BeginPage();
|
||||
|
||||
return rv;
|
||||
|
|
@ -559,18 +535,6 @@ nsDeviceContext::EndPage(void)
|
|||
{
|
||||
nsresult rv = mPrintTarget->EndPage();
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// We need to release the CGContextRef in the surface here, plus it's
|
||||
// not something you would want anyway, as these CGContextRefs are only
|
||||
// good for one page. But we need to keep a cached reference to it, since
|
||||
// CreateRenderingContext() may try to access it when mPrintTarget
|
||||
// would normally be null. See bug 665218. If we just stop nulling out
|
||||
// mPrintTarget here (and thereby make that our cached copy), we'll
|
||||
// break all our null checks on mPrintTarget. See bug 684622.
|
||||
mCachedPrintTarget = mPrintTarget;
|
||||
mPrintTarget = nullptr;
|
||||
#endif
|
||||
|
||||
if (mDeviceContextSpec)
|
||||
mDeviceContextSpec->EndPage();
|
||||
|
||||
|
|
|
|||
|
|
@ -300,9 +300,6 @@ private:
|
|||
nsCOMPtr<nsIScreenManager> mScreenManager;
|
||||
nsCOMPtr<nsIDeviceContextSpec> mDeviceContextSpec;
|
||||
RefPtr<PrintTarget> mPrintTarget;
|
||||
#ifdef XP_MACOSX
|
||||
RefPtr<PrintTarget> mCachedPrintTarget;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
bool mIsInitialized;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PrintTargetCG.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include "cairo-quartz.h"
|
||||
#include "mozilla/gfx/HelpersCairo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
PrintTargetCG::PrintTargetCG(cairo_surface_t* aCairoSurface,
|
||||
const IntSize& aSize)
|
||||
: PrintTarget(aCairoSurface, aSize)
|
||||
{
|
||||
// TODO: Add memory reporting like gfxQuartzSurface.
|
||||
//RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PrintTargetCG>
|
||||
PrintTargetCG::CreateOrNull(const IntSize& aSize, gfxImageFormat aFormat)
|
||||
{
|
||||
if (!Factory::CheckSurfaceSize(aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int width = static_cast<unsigned int>(aSize.width);
|
||||
unsigned int height = static_cast<unsigned int>(aSize.height);
|
||||
|
||||
cairo_format_t cformat = GfxFormatToCairoFormat(aFormat);
|
||||
cairo_surface_t* surface =
|
||||
cairo_quartz_surface_create(cformat, width, height);
|
||||
|
||||
if (cairo_surface_status(surface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The new object takes ownership of our surface reference.
|
||||
RefPtr<PrintTargetCG> target = new PrintTargetCG(surface, aSize);
|
||||
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PrintTargetCG>
|
||||
PrintTargetCG::CreateOrNull(CGContextRef aContext, const IntSize& aSize)
|
||||
{
|
||||
if (!Factory::CheckSurfaceSize(aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int width = static_cast<unsigned int>(aSize.width);
|
||||
unsigned int height = static_cast<unsigned int>(aSize.height);
|
||||
|
||||
cairo_surface_t* surface =
|
||||
cairo_quartz_surface_create_for_cg_context(aContext, width, height);
|
||||
|
||||
if (cairo_surface_status(surface)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The new object takes ownership of our surface reference.
|
||||
RefPtr<PrintTargetCG> target = new PrintTargetCG(surface, aSize);
|
||||
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
static size_t
|
||||
PutBytesNull(void* info, const void* buffer, size_t count)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTargetCG::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
||||
{
|
||||
if (!mRefDT) {
|
||||
const IntSize size(1, 1);
|
||||
|
||||
CGDataConsumerCallbacks callbacks = {PutBytesNull, nullptr};
|
||||
CGDataConsumerRef consumer = CGDataConsumerCreate(nullptr, &callbacks);
|
||||
CGContextRef pdfContext = CGPDFContextCreate(consumer, nullptr, nullptr);
|
||||
CGDataConsumerRelease(consumer);
|
||||
|
||||
cairo_surface_t* similar =
|
||||
cairo_quartz_surface_create_for_cg_context(
|
||||
pdfContext, size.width, size.height);
|
||||
|
||||
CGContextRelease(pdfContext);
|
||||
|
||||
if (cairo_surface_status(similar)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt =
|
||||
Factory::CreateDrawTargetForCairoSurface(similar, size);
|
||||
|
||||
// The DT addrefs the surface, so we need drop our own reference to it:
|
||||
cairo_surface_destroy(similar);
|
||||
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aRecorder) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mRefDT = dt.forget();
|
||||
}
|
||||
return do_AddRef(mRefDT);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_PRINTTARGETCG_H
|
||||
#define MOZILLA_GFX_PRINTTARGETCG_H
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include "PrintTarget.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* CoreGraphics printing target.
|
||||
*
|
||||
* Note that a CGContextRef obtained from PMSessionGetCGGraphicsContext is
|
||||
* valid only for the current page. As a consequence instances of this class
|
||||
* should only be used to print a single page.
|
||||
*/
|
||||
class PrintTargetCG final : public PrintTarget
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<PrintTargetCG>
|
||||
CreateOrNull(const IntSize& aSize, gfxImageFormat aFormat);
|
||||
|
||||
static already_AddRefed<PrintTargetCG>
|
||||
CreateOrNull(CGContextRef aContext, const IntSize& aSize);
|
||||
|
||||
virtual already_AddRefed<DrawTarget>
|
||||
GetReferenceDrawTarget(DrawEventRecorder* aRecorder) final;
|
||||
|
||||
private:
|
||||
PrintTargetCG(cairo_surface_t* aCairoSurface,
|
||||
const IntSize& aSize);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_PRINTTARGETCG_H */
|
||||
|
|
@ -1,800 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "gfxCoreTextShaper.h"
|
||||
#include "gfxMacFont.h"
|
||||
#include "gfxFontUtils.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// standard font descriptors that we construct the first time they're needed
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sIndicFeaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sIndicDisableLigaturesDescriptor = nullptr;
|
||||
|
||||
static CFStringRef sCTWritingDirectionAttributeName = nullptr;
|
||||
|
||||
// See CTStringAttributes.h
|
||||
enum {
|
||||
kMyCTWritingDirectionEmbedding = (0 << 1),
|
||||
kMyCTWritingDirectionOverride = (1 << 1)
|
||||
};
|
||||
|
||||
// Helper to create a CFDictionary with the right attributes for shaping our
|
||||
// text, including imposing the given directionality.
|
||||
// This will only be called if we're on 10.8 or later.
|
||||
CFDictionaryRef
|
||||
gfxCoreTextShaper::CreateAttrDict(bool aRightToLeft)
|
||||
{
|
||||
// Because we always shape unidirectional runs, and may have applied
|
||||
// directional overrides, we want to force a direction rather than
|
||||
// allowing CoreText to do its own unicode-based bidi processing.
|
||||
SInt16 dirOverride = kMyCTWritingDirectionOverride |
|
||||
(aRightToLeft ? kCTWritingDirectionRightToLeft
|
||||
: kCTWritingDirectionLeftToRight);
|
||||
CFNumberRef dirNumber =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type, &dirOverride);
|
||||
CFArrayRef dirArray =
|
||||
::CFArrayCreate(kCFAllocatorDefault,
|
||||
(const void **) &dirNumber, 1,
|
||||
&kCFTypeArrayCallBacks);
|
||||
::CFRelease(dirNumber);
|
||||
CFTypeRef attrs[] = { kCTFontAttributeName, sCTWritingDirectionAttributeName };
|
||||
CFTypeRef values[] = { mCTFont, dirArray };
|
||||
CFDictionaryRef attrDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
attrs, values, ArrayLength(attrs),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(dirArray);
|
||||
return attrDict;
|
||||
}
|
||||
|
||||
CFDictionaryRef
|
||||
gfxCoreTextShaper::CreateAttrDictWithoutDirection()
|
||||
{
|
||||
CFTypeRef attrs[] = { kCTFontAttributeName };
|
||||
CFTypeRef values[] = { mCTFont };
|
||||
CFDictionaryRef attrDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
attrs, values, ArrayLength(attrs),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
return attrDict;
|
||||
}
|
||||
|
||||
gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
|
||||
: gfxFontShaper(aFont)
|
||||
, mAttributesDictLTR(nullptr)
|
||||
, mAttributesDictRTL(nullptr)
|
||||
{
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized) {
|
||||
CFStringRef* pstr = (CFStringRef*)
|
||||
dlsym(RTLD_DEFAULT, "kCTWritingDirectionAttributeName");
|
||||
if (pstr) {
|
||||
sCTWritingDirectionAttributeName = *pstr;
|
||||
}
|
||||
sInitialized = true;
|
||||
}
|
||||
|
||||
// Create our CTFontRef
|
||||
mCTFont = CreateCTFontWithFeatures(aFont->GetAdjustedSize(),
|
||||
GetDefaultFeaturesDescriptor());
|
||||
}
|
||||
|
||||
gfxCoreTextShaper::~gfxCoreTextShaper()
|
||||
{
|
||||
if (mAttributesDictLTR) {
|
||||
::CFRelease(mAttributesDictLTR);
|
||||
}
|
||||
if (mAttributesDictRTL) {
|
||||
::CFRelease(mAttributesDictRTL);
|
||||
}
|
||||
if (mCTFont) {
|
||||
::CFRelease(mCTFont);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsBuggyIndicScript(unicode::Script aScript)
|
||||
{
|
||||
return aScript == unicode::Script::BENGALI ||
|
||||
aScript == unicode::Script::KANNADA;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
|
||||
const char16_t *aText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Script aScript,
|
||||
bool aVertical,
|
||||
gfxShapedText *aShapedText)
|
||||
{
|
||||
// Create a CFAttributedString with text and style info, so we can use CoreText to lay it out.
|
||||
bool isRightToLeft = aShapedText->IsRightToLeft();
|
||||
const UniChar* text = reinterpret_cast<const UniChar*>(aText);
|
||||
uint32_t length = aLength;
|
||||
|
||||
uint32_t startOffset;
|
||||
CFStringRef stringObj;
|
||||
CFDictionaryRef attrObj;
|
||||
|
||||
if (sCTWritingDirectionAttributeName) {
|
||||
startOffset = 0;
|
||||
stringObj = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
|
||||
text, length,
|
||||
kCFAllocatorNull);
|
||||
|
||||
// Get an attributes dictionary suitable for shaping text in the
|
||||
// current direction, creating it if necessary.
|
||||
attrObj = isRightToLeft ? mAttributesDictRTL : mAttributesDictLTR;
|
||||
if (!attrObj) {
|
||||
attrObj = CreateAttrDict(isRightToLeft);
|
||||
(isRightToLeft ? mAttributesDictRTL : mAttributesDictLTR) = attrObj;
|
||||
}
|
||||
} else {
|
||||
// OS is too old to support kCTWritingDirectionAttributeName:
|
||||
// we need to bidi-wrap the text if the run is RTL,
|
||||
// or if it is an LTR run but may contain (overridden) RTL chars
|
||||
bool bidiWrap = isRightToLeft;
|
||||
if (!bidiWrap && !aShapedText->TextIs8Bit()) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (gfxFontUtils::PotentialRTLChar(aText[i])) {
|
||||
bidiWrap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a possibility of any bidi, we wrap the text with
|
||||
// direction overrides to ensure neutrals or characters that were
|
||||
// bidi-overridden in HTML behave properly.
|
||||
static const UniChar beginLTR[] = { 0x202d, 0x20 };
|
||||
static const UniChar beginRTL[] = { 0x202e, 0x20 };
|
||||
static const UniChar endBidiWrap[] = { 0x20, 0x2e, 0x202c };
|
||||
|
||||
if (bidiWrap) {
|
||||
startOffset = isRightToLeft ? ArrayLength(beginRTL)
|
||||
: ArrayLength(beginLTR);
|
||||
CFMutableStringRef mutableString =
|
||||
::CFStringCreateMutable(kCFAllocatorDefault,
|
||||
length + startOffset +
|
||||
ArrayLength(endBidiWrap));
|
||||
::CFStringAppendCharacters(mutableString,
|
||||
isRightToLeft ? beginRTL : beginLTR,
|
||||
startOffset);
|
||||
::CFStringAppendCharacters(mutableString, text, length);
|
||||
::CFStringAppendCharacters(mutableString, endBidiWrap,
|
||||
ArrayLength(endBidiWrap));
|
||||
stringObj = mutableString;
|
||||
} else {
|
||||
startOffset = 0;
|
||||
stringObj =
|
||||
::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
|
||||
text, length,
|
||||
kCFAllocatorNull);
|
||||
}
|
||||
|
||||
// Get an attributes dictionary suitable for shaping text,
|
||||
// creating it if necessary. (This dict is not LTR-specific,
|
||||
// but we use that field to store it anyway.)
|
||||
if (!mAttributesDictLTR) {
|
||||
mAttributesDictLTR = CreateAttrDictWithoutDirection();
|
||||
}
|
||||
attrObj = mAttributesDictLTR;
|
||||
}
|
||||
|
||||
CTFontRef tempCTFont = nullptr;
|
||||
if (IsBuggyIndicScript(aScript)) {
|
||||
// To work around buggy Indic AAT fonts shipped with OS X,
|
||||
// we re-enable the Line Initial Smart Swashes feature that is needed
|
||||
// for "split vowels" to work in at least Bengali and Kannada fonts.
|
||||
// Affected fonts include Bangla MN, Bangla Sangam MN, Kannada MN,
|
||||
// Kannada Sangam MN. See bugs 686225, 728557, 953231, 1145515.
|
||||
tempCTFont =
|
||||
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
|
||||
aShapedText->DisableLigatures()
|
||||
? GetIndicDisableLigaturesDescriptor()
|
||||
: GetIndicFeaturesDescriptor());
|
||||
} else if (aShapedText->DisableLigatures()) {
|
||||
// For letterspacing (or maybe other situations) we need to make
|
||||
// a copy of the CTFont with the ligature feature disabled.
|
||||
tempCTFont =
|
||||
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
|
||||
GetDisableLigaturesDescriptor());
|
||||
}
|
||||
|
||||
// For the disabled-ligature or buggy-indic-font case, we need to replace
|
||||
// the standard CTFont in the attribute dictionary with a tweaked version.
|
||||
CFMutableDictionaryRef mutableAttr = nullptr;
|
||||
if (tempCTFont) {
|
||||
mutableAttr = ::CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 2,
|
||||
attrObj);
|
||||
::CFDictionaryReplaceValue(mutableAttr,
|
||||
kCTFontAttributeName, tempCTFont);
|
||||
// Having created the dict, we're finished with our temporary
|
||||
// Indic and/or ligature-disabled CTFontRef.
|
||||
::CFRelease(tempCTFont);
|
||||
attrObj = mutableAttr;
|
||||
}
|
||||
|
||||
// Now we can create an attributed string
|
||||
CFAttributedStringRef attrStringObj =
|
||||
::CFAttributedStringCreate(kCFAllocatorDefault, stringObj, attrObj);
|
||||
::CFRelease(stringObj);
|
||||
|
||||
// Create the CoreText line from our string, then we're done with it
|
||||
CTLineRef line = ::CTLineCreateWithAttributedString(attrStringObj);
|
||||
::CFRelease(attrStringObj);
|
||||
|
||||
// and finally retrieve the glyph data and store into the gfxTextRun
|
||||
CFArrayRef glyphRuns = ::CTLineGetGlyphRuns(line);
|
||||
uint32_t numRuns = ::CFArrayGetCount(glyphRuns);
|
||||
|
||||
// Iterate through the glyph runs.
|
||||
// Note that this includes the bidi wrapper, so we have to be careful
|
||||
// not to include the extra glyphs from there
|
||||
bool success = true;
|
||||
for (uint32_t runIndex = 0; runIndex < numRuns; runIndex++) {
|
||||
CTRunRef aCTRun =
|
||||
(CTRunRef)::CFArrayGetValueAtIndex(glyphRuns, runIndex);
|
||||
// If the range is purely within bidi-wrapping text, ignore it.
|
||||
CFRange range = ::CTRunGetStringRange(aCTRun);
|
||||
if (uint32_t(range.location + range.length) <= startOffset ||
|
||||
range.location - startOffset >= aLength) {
|
||||
continue;
|
||||
}
|
||||
CFDictionaryRef runAttr = ::CTRunGetAttributes(aCTRun);
|
||||
if (runAttr != attrObj) {
|
||||
// If Core Text manufactured a new dictionary, this may indicate
|
||||
// unexpected font substitution. In that case, we fail (and fall
|
||||
// back to harfbuzz shaping)...
|
||||
const void* font1 =
|
||||
::CFDictionaryGetValue(attrObj, kCTFontAttributeName);
|
||||
const void* font2 =
|
||||
::CFDictionaryGetValue(runAttr, kCTFontAttributeName);
|
||||
if (font1 != font2) {
|
||||
// ...except that if the fallback was only for a variation
|
||||
// selector or join control that is otherwise unsupported,
|
||||
// we just ignore it.
|
||||
if (range.length == 1) {
|
||||
char16_t ch = aText[range.location - startOffset];
|
||||
if (gfxFontUtils::IsJoinControl(ch) ||
|
||||
gfxFontUtils::IsVarSelector(ch)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_WARNING("unexpected font fallback in Core Text");
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SetGlyphsFromRun(aShapedText, aOffset, aLength, aCTRun,
|
||||
startOffset) != NS_OK) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mutableAttr) {
|
||||
::CFRelease(mutableAttr);
|
||||
}
|
||||
::CFRelease(line);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
#define SMALL_GLYPH_RUN 128 // preallocated size of our auto arrays for per-glyph data;
|
||||
// some testing indicates that 90%+ of glyph runs will fit
|
||||
// without requiring a separate allocation
|
||||
|
||||
nsresult
|
||||
gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
CTRunRef aCTRun,
|
||||
int32_t aStringOffset)
|
||||
{
|
||||
// The word has been bidi-wrapped; aStringOffset is the number
|
||||
// of chars at the beginning of the CTLine that we should skip.
|
||||
// aCTRun is a glyph run from the CoreText layout process.
|
||||
|
||||
int32_t direction = aShapedText->IsRightToLeft() ? -1 : 1;
|
||||
|
||||
int32_t numGlyphs = ::CTRunGetGlyphCount(aCTRun);
|
||||
if (numGlyphs == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t wordLength = aLength;
|
||||
|
||||
// character offsets get really confusing here, as we have to keep track of
|
||||
// (a) the text in the actual textRun we're constructing
|
||||
// (c) the string that was handed to CoreText, which contains the text of the font run
|
||||
// plus directional-override padding
|
||||
// (d) the CTRun currently being processed, which may be a sub-run of the CoreText line
|
||||
// (but may extend beyond the actual font run into the bidi wrapping text).
|
||||
// aStringOffset tells us how many initial characters of the line to ignore.
|
||||
|
||||
// get the source string range within the CTLine's text
|
||||
CFRange stringRange = ::CTRunGetStringRange(aCTRun);
|
||||
// skip the run if it is entirely outside the actual range of the font run
|
||||
if (stringRange.location - aStringOffset + stringRange.length <= 0 ||
|
||||
stringRange.location - aStringOffset >= wordLength) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// retrieve the laid-out glyph data from the CTRun
|
||||
UniquePtr<CGGlyph[]> glyphsArray;
|
||||
UniquePtr<CGPoint[]> positionsArray;
|
||||
UniquePtr<CFIndex[]> glyphToCharArray;
|
||||
const CGGlyph* glyphs = nullptr;
|
||||
const CGPoint* positions = nullptr;
|
||||
const CFIndex* glyphToChar = nullptr;
|
||||
|
||||
// Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
|
||||
// and so allocating a new array and copying data with CTRunGetGlyphs
|
||||
// will be extremely rare.
|
||||
// If this were not the case, we could use an AutoTArray<> to
|
||||
// try and avoid the heap allocation for small runs.
|
||||
// It's possible that some future change to CoreText will mean that
|
||||
// CTRunGetGlyphsPtr fails more often; if this happens, AutoTArray<>
|
||||
// may become an attractive option.
|
||||
glyphs = ::CTRunGetGlyphsPtr(aCTRun);
|
||||
if (!glyphs) {
|
||||
glyphsArray = MakeUniqueFallible<CGGlyph[]>(numGlyphs);
|
||||
if (!glyphsArray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
::CTRunGetGlyphs(aCTRun, ::CFRangeMake(0, 0), glyphsArray.get());
|
||||
glyphs = glyphsArray.get();
|
||||
}
|
||||
|
||||
positions = ::CTRunGetPositionsPtr(aCTRun);
|
||||
if (!positions) {
|
||||
positionsArray = MakeUniqueFallible<CGPoint[]>(numGlyphs);
|
||||
if (!positionsArray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
::CTRunGetPositions(aCTRun, ::CFRangeMake(0, 0), positionsArray.get());
|
||||
positions = positionsArray.get();
|
||||
}
|
||||
|
||||
// Remember that the glyphToChar indices relate to the CoreText line,
|
||||
// not to the beginning of the textRun, the font run,
|
||||
// or the stringRange of the glyph run
|
||||
glyphToChar = ::CTRunGetStringIndicesPtr(aCTRun);
|
||||
if (!glyphToChar) {
|
||||
glyphToCharArray = MakeUniqueFallible<CFIndex[]>(numGlyphs);
|
||||
if (!glyphToCharArray) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
::CTRunGetStringIndices(aCTRun, ::CFRangeMake(0, 0), glyphToCharArray.get());
|
||||
glyphToChar = glyphToCharArray.get();
|
||||
}
|
||||
|
||||
double runWidth = ::CTRunGetTypographicBounds(aCTRun, ::CFRangeMake(0, 0),
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
AutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
|
||||
gfxShapedText::CompressedGlyph *charGlyphs =
|
||||
aShapedText->GetCharacterGlyphs() + aOffset;
|
||||
|
||||
// CoreText gives us the glyphindex-to-charindex mapping, which relates each glyph
|
||||
// to a source text character; we also need the charindex-to-glyphindex mapping to
|
||||
// find the glyph for a given char. Note that some chars may not map to any glyph
|
||||
// (ligature continuations), and some may map to several glyphs (eg Indic split vowels).
|
||||
// We set the glyph index to NO_GLYPH for chars that have no associated glyph, and we
|
||||
// record the last glyph index for cases where the char maps to several glyphs,
|
||||
// so that our clumping will include all the glyph fragments for the character.
|
||||
|
||||
// The charToGlyph array is indexed by char position within the stringRange of the glyph run.
|
||||
|
||||
static const int32_t NO_GLYPH = -1;
|
||||
AutoTArray<int32_t,SMALL_GLYPH_RUN> charToGlyphArray;
|
||||
if (!charToGlyphArray.SetLength(stringRange.length, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t *charToGlyph = charToGlyphArray.Elements();
|
||||
for (int32_t offset = 0; offset < stringRange.length; ++offset) {
|
||||
charToGlyph[offset] = NO_GLYPH;
|
||||
}
|
||||
for (int32_t i = 0; i < numGlyphs; ++i) {
|
||||
int32_t loc = glyphToChar[i] - stringRange.location;
|
||||
if (loc >= 0 && loc < stringRange.length) {
|
||||
charToGlyph[loc] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Find character and glyph clumps that correspond, allowing for ligatures,
|
||||
// indic reordering, split glyphs, etc.
|
||||
//
|
||||
// The idea is that we'll find a character sequence starting at the first char of stringRange,
|
||||
// and extend it until it includes the character associated with the first glyph;
|
||||
// we also extend it as long as there are "holes" in the range of glyphs. So we
|
||||
// will eventually have a contiguous sequence of characters, starting at the beginning
|
||||
// of the range, that map to a contiguous sequence of glyphs, starting at the beginning
|
||||
// of the glyph array. That's a clump; then we update the starting positions and repeat.
|
||||
//
|
||||
// NB: In the case of RTL layouts, we iterate over the stringRange in reverse.
|
||||
//
|
||||
|
||||
// This may find characters that fall outside the range 0:wordLength,
|
||||
// so we won't necessarily use everything we find here.
|
||||
|
||||
bool isRightToLeft = aShapedText->IsRightToLeft();
|
||||
int32_t glyphStart = 0; // looking for a clump that starts at this glyph index
|
||||
int32_t charStart = isRightToLeft ?
|
||||
stringRange.length - 1 : 0; // and this char index (in the stringRange of the glyph run)
|
||||
|
||||
while (glyphStart < numGlyphs) { // keep finding groups until all glyphs are accounted for
|
||||
bool inOrder = true;
|
||||
int32_t charEnd = glyphToChar[glyphStart] - stringRange.location;
|
||||
NS_WARNING_ASSERTION(
|
||||
charEnd >= 0 && charEnd < stringRange.length,
|
||||
"glyph-to-char mapping points outside string range");
|
||||
// clamp charEnd to the valid range of the string
|
||||
charEnd = std::max(charEnd, 0);
|
||||
charEnd = std::min(charEnd, int32_t(stringRange.length));
|
||||
|
||||
int32_t glyphEnd = glyphStart;
|
||||
int32_t charLimit = isRightToLeft ? -1 : stringRange.length;
|
||||
do {
|
||||
// This is normally executed once for each iteration of the outer loop,
|
||||
// but in unusual cases where the character/glyph association is complex,
|
||||
// the initial character range might correspond to a non-contiguous
|
||||
// glyph range with "holes" in it. If so, we will repeat this loop to
|
||||
// extend the character range until we have a contiguous glyph sequence.
|
||||
NS_ASSERTION((direction > 0 && charEnd < charLimit) ||
|
||||
(direction < 0 && charEnd > charLimit),
|
||||
"no characters left in range?");
|
||||
charEnd += direction;
|
||||
while (charEnd != charLimit && charToGlyph[charEnd] == NO_GLYPH) {
|
||||
charEnd += direction;
|
||||
}
|
||||
|
||||
// find the maximum glyph index covered by the clump so far
|
||||
if (isRightToLeft) {
|
||||
for (int32_t i = charStart; i > charEnd; --i) {
|
||||
if (charToGlyph[i] != NO_GLYPH) {
|
||||
// update extent of glyph range
|
||||
glyphEnd = std::max(glyphEnd, charToGlyph[i] + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int32_t i = charStart; i < charEnd; ++i) {
|
||||
if (charToGlyph[i] != NO_GLYPH) {
|
||||
// update extent of glyph range
|
||||
glyphEnd = std::max(glyphEnd, charToGlyph[i] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (glyphEnd == glyphStart + 1) {
|
||||
// for the common case of a single-glyph clump, we can skip the following checks
|
||||
break;
|
||||
}
|
||||
|
||||
if (glyphEnd == glyphStart) {
|
||||
// no glyphs, try to extend the clump
|
||||
continue;
|
||||
}
|
||||
|
||||
// check whether all glyphs in the range are associated with the characters
|
||||
// in our clump; if not, we have a discontinuous range, and should extend it
|
||||
// unless we've reached the end of the text
|
||||
bool allGlyphsAreWithinCluster = true;
|
||||
int32_t prevGlyphCharIndex = charStart;
|
||||
for (int32_t i = glyphStart; i < glyphEnd; ++i) {
|
||||
int32_t glyphCharIndex = glyphToChar[i] - stringRange.location;
|
||||
if (isRightToLeft) {
|
||||
if (glyphCharIndex > charStart || glyphCharIndex <= charEnd) {
|
||||
allGlyphsAreWithinCluster = false;
|
||||
break;
|
||||
}
|
||||
if (glyphCharIndex > prevGlyphCharIndex) {
|
||||
inOrder = false;
|
||||
}
|
||||
prevGlyphCharIndex = glyphCharIndex;
|
||||
} else {
|
||||
if (glyphCharIndex < charStart || glyphCharIndex >= charEnd) {
|
||||
allGlyphsAreWithinCluster = false;
|
||||
break;
|
||||
}
|
||||
if (glyphCharIndex < prevGlyphCharIndex) {
|
||||
inOrder = false;
|
||||
}
|
||||
prevGlyphCharIndex = glyphCharIndex;
|
||||
}
|
||||
}
|
||||
if (allGlyphsAreWithinCluster) {
|
||||
break;
|
||||
}
|
||||
} while (charEnd != charLimit);
|
||||
|
||||
NS_WARNING_ASSERTION(glyphStart < glyphEnd,
|
||||
"character/glyph clump contains no glyphs!");
|
||||
if (glyphStart == glyphEnd) {
|
||||
++glyphStart; // make progress - avoid potential infinite loop
|
||||
charStart = charEnd;
|
||||
continue;
|
||||
}
|
||||
|
||||
NS_WARNING_ASSERTION(charStart != charEnd,
|
||||
"character/glyph clump contains no characters!");
|
||||
if (charStart == charEnd) {
|
||||
glyphStart = glyphEnd; // this is bad - we'll discard the glyph(s),
|
||||
// as there's nowhere to attach them
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now charStart..charEnd is a ligature clump, corresponding to glyphStart..glyphEnd;
|
||||
// Set baseCharIndex to the char we'll actually attach the glyphs to (1st of ligature),
|
||||
// and endCharIndex to the limit (position beyond the last char),
|
||||
// adjusting for the offset of the stringRange relative to the textRun.
|
||||
int32_t baseCharIndex, endCharIndex;
|
||||
if (isRightToLeft) {
|
||||
while (charEnd >= 0 && charToGlyph[charEnd] == NO_GLYPH) {
|
||||
charEnd--;
|
||||
}
|
||||
baseCharIndex = charEnd + stringRange.location - aStringOffset + 1;
|
||||
endCharIndex = charStart + stringRange.location - aStringOffset + 1;
|
||||
} else {
|
||||
while (charEnd < stringRange.length && charToGlyph[charEnd] == NO_GLYPH) {
|
||||
charEnd++;
|
||||
}
|
||||
baseCharIndex = charStart + stringRange.location - aStringOffset;
|
||||
endCharIndex = charEnd + stringRange.location - aStringOffset;
|
||||
}
|
||||
|
||||
// Then we check if the clump falls outside our actual string range; if so, just go to the next.
|
||||
if (endCharIndex <= 0 || baseCharIndex >= wordLength) {
|
||||
glyphStart = glyphEnd;
|
||||
charStart = charEnd;
|
||||
continue;
|
||||
}
|
||||
// Ensure we won't try to go beyond the valid length of the word's text
|
||||
baseCharIndex = std::max(baseCharIndex, 0);
|
||||
endCharIndex = std::min(endCharIndex, wordLength);
|
||||
|
||||
// Now we're ready to set the glyph info in the textRun; measure the glyph width
|
||||
// of the first (perhaps only) glyph, to see if it is "Simple"
|
||||
int32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
|
||||
double toNextGlyph;
|
||||
if (glyphStart < numGlyphs-1) {
|
||||
toNextGlyph = positions[glyphStart+1].x - positions[glyphStart].x;
|
||||
} else {
|
||||
toNextGlyph = positions[0].x + runWidth - positions[glyphStart].x;
|
||||
}
|
||||
int32_t advance = int32_t(toNextGlyph * appUnitsPerDevUnit);
|
||||
|
||||
// Check if it's a simple one-to-one mapping
|
||||
int32_t glyphsInClump = glyphEnd - glyphStart;
|
||||
if (glyphsInClump == 1 &&
|
||||
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyphs[glyphStart]) &&
|
||||
gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
|
||||
charGlyphs[baseCharIndex].IsClusterStart() &&
|
||||
positions[glyphStart].y == 0.0)
|
||||
{
|
||||
charGlyphs[baseCharIndex].SetSimpleGlyph(advance,
|
||||
glyphs[glyphStart]);
|
||||
} else {
|
||||
// collect all glyphs in a list to be assigned to the first char;
|
||||
// there must be at least one in the clump, and we already measured its advance,
|
||||
// hence the placement of the loop-exit test and the measurement of the next glyph
|
||||
while (1) {
|
||||
gfxTextRun::DetailedGlyph *details = detailedGlyphs.AppendElement();
|
||||
details->mGlyphID = glyphs[glyphStart];
|
||||
details->mXOffset = 0;
|
||||
details->mYOffset = -positions[glyphStart].y * appUnitsPerDevUnit;
|
||||
details->mAdvance = advance;
|
||||
if (++glyphStart >= glyphEnd) {
|
||||
break;
|
||||
}
|
||||
if (glyphStart < numGlyphs-1) {
|
||||
toNextGlyph = positions[glyphStart+1].x - positions[glyphStart].x;
|
||||
} else {
|
||||
toNextGlyph = positions[0].x + runWidth - positions[glyphStart].x;
|
||||
}
|
||||
advance = int32_t(toNextGlyph * appUnitsPerDevUnit);
|
||||
}
|
||||
|
||||
gfxTextRun::CompressedGlyph textRunGlyph;
|
||||
textRunGlyph.SetComplex(charGlyphs[baseCharIndex].IsClusterStart(),
|
||||
true, detailedGlyphs.Length());
|
||||
aShapedText->SetGlyphs(aOffset + baseCharIndex, textRunGlyph,
|
||||
detailedGlyphs.Elements());
|
||||
|
||||
detailedGlyphs.Clear();
|
||||
}
|
||||
|
||||
// the rest of the chars in the group are ligature continuations, no associated glyphs
|
||||
while (++baseCharIndex != endCharIndex && baseCharIndex < wordLength) {
|
||||
gfxShapedText::CompressedGlyph &shapedTextGlyph = charGlyphs[baseCharIndex];
|
||||
NS_ASSERTION(!shapedTextGlyph.IsSimpleGlyph(), "overwriting a simple glyph");
|
||||
shapedTextGlyph.SetComplex(inOrder && shapedTextGlyph.IsClusterStart(), false, 0);
|
||||
}
|
||||
|
||||
glyphStart = glyphEnd;
|
||||
charStart = charEnd;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#undef SMALL_GLYPH_RUN
|
||||
|
||||
// Construct the font attribute descriptor that we'll apply by default when
|
||||
// creating a CTFontRef. This will turn off line-edge swashes by default,
|
||||
// because we don't know the actual line breaks when doing glyph shaping.
|
||||
|
||||
// We also cache feature descriptors for shaping with disabled ligatures, and
|
||||
// for buggy Indic AAT font workarounds, created on an as-needed basis.
|
||||
|
||||
#define MAX_FEATURES 3 // max used by any of our Get*Descriptor functions
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::CreateFontFeaturesDescriptor(
|
||||
const std::pair<SInt16,SInt16> aFeatures[],
|
||||
size_t aCount)
|
||||
{
|
||||
MOZ_ASSERT(aCount <= MAX_FEATURES);
|
||||
|
||||
CFDictionaryRef featureSettings[MAX_FEATURES];
|
||||
|
||||
for (size_t i = 0; i < aCount; i++) {
|
||||
CFNumberRef type = ::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&aFeatures[i].first);
|
||||
CFNumberRef selector = ::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&aFeatures[i].second);
|
||||
|
||||
CFTypeRef keys[] = { kCTFontFeatureTypeIdentifierKey,
|
||||
kCTFontFeatureSelectorIdentifierKey };
|
||||
CFTypeRef values[] = { type, selector };
|
||||
featureSettings[i] =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) keys,
|
||||
(const void **) values,
|
||||
ArrayLength(keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
::CFRelease(selector);
|
||||
::CFRelease(type);
|
||||
}
|
||||
|
||||
CFArrayRef featuresArray =
|
||||
::CFArrayCreate(kCFAllocatorDefault,
|
||||
(const void **) featureSettings,
|
||||
aCount, // not ArrayLength(featureSettings), as we
|
||||
// may not have used all the allocated slots
|
||||
&kCFTypeArrayCallBacks);
|
||||
|
||||
for (size_t i = 0; i < aCount; i++) {
|
||||
::CFRelease(featureSettings[i]);
|
||||
}
|
||||
|
||||
const CFTypeRef attrKeys[] = { kCTFontFeatureSettingsAttribute };
|
||||
const CFTypeRef attrValues[] = { featuresArray };
|
||||
CFDictionaryRef attributesDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) attrKeys,
|
||||
(const void **) attrValues,
|
||||
ArrayLength(attrKeys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(featuresArray);
|
||||
|
||||
CTFontDescriptorRef descriptor =
|
||||
::CTFontDescriptorCreateWithAttributes(attributesDict);
|
||||
::CFRelease(attributesDict);
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetDefaultFeaturesDescriptor()
|
||||
{
|
||||
if (sDefaultFeaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kDefaultFeatures[] = {
|
||||
{ kSmartSwashType, kLineInitialSwashesOffSelector },
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector }
|
||||
};
|
||||
sDefaultFeaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kDefaultFeatures,
|
||||
ArrayLength(kDefaultFeatures));
|
||||
}
|
||||
return sDefaultFeaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetDisableLigaturesDescriptor()
|
||||
{
|
||||
if (sDisableLigaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kDisableLigatures[] = {
|
||||
{ kSmartSwashType, kLineInitialSwashesOffSelector },
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector },
|
||||
{ kLigaturesType, kCommonLigaturesOffSelector }
|
||||
};
|
||||
sDisableLigaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kDisableLigatures,
|
||||
ArrayLength(kDisableLigatures));
|
||||
}
|
||||
return sDisableLigaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetIndicFeaturesDescriptor()
|
||||
{
|
||||
if (sIndicFeaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kIndicFeatures[] = {
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector }
|
||||
};
|
||||
sIndicFeaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kIndicFeatures,
|
||||
ArrayLength(kIndicFeatures));
|
||||
}
|
||||
return sIndicFeaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetIndicDisableLigaturesDescriptor()
|
||||
{
|
||||
if (sIndicDisableLigaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kIndicDisableLigatures[] = {
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector },
|
||||
{ kLigaturesType, kCommonLigaturesOffSelector }
|
||||
};
|
||||
sIndicDisableLigaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kIndicDisableLigatures,
|
||||
ArrayLength(kIndicDisableLigatures));
|
||||
}
|
||||
return sIndicDisableLigaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontRef
|
||||
gfxCoreTextShaper::CreateCTFontWithFeatures(CGFloat aSize,
|
||||
CTFontDescriptorRef aDescriptor)
|
||||
{
|
||||
gfxMacFont *f = static_cast<gfxMacFont*>(mFont);
|
||||
return ::CTFontCreateWithGraphicsFont(f->GetCGFontRef(), aSize, nullptr,
|
||||
aDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
gfxCoreTextShaper::Shutdown() // [static]
|
||||
{
|
||||
if (sIndicDisableLigaturesDescriptor != nullptr) {
|
||||
::CFRelease(sIndicDisableLigaturesDescriptor);
|
||||
sIndicDisableLigaturesDescriptor = nullptr;
|
||||
}
|
||||
if (sIndicFeaturesDescriptor != nullptr) {
|
||||
::CFRelease(sIndicFeaturesDescriptor);
|
||||
sIndicFeaturesDescriptor = nullptr;
|
||||
}
|
||||
if (sDisableLigaturesDescriptor != nullptr) {
|
||||
::CFRelease(sDisableLigaturesDescriptor);
|
||||
sDisableLigaturesDescriptor = nullptr;
|
||||
}
|
||||
if (sDefaultFeaturesDescriptor != nullptr) {
|
||||
::CFRelease(sDefaultFeaturesDescriptor);
|
||||
sDefaultFeaturesDescriptor = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_CORETEXTSHAPER_H
|
||||
#define GFX_CORETEXTSHAPER_H
|
||||
|
||||
#include "gfxFont.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
class gfxMacFont;
|
||||
|
||||
class gfxCoreTextShaper : public gfxFontShaper {
|
||||
public:
|
||||
explicit gfxCoreTextShaper(gfxMacFont *aFont);
|
||||
|
||||
virtual ~gfxCoreTextShaper();
|
||||
|
||||
virtual bool ShapeText(DrawTarget *aDrawTarget,
|
||||
const char16_t *aText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Script aScript,
|
||||
bool aVertical,
|
||||
gfxShapedText *aShapedText);
|
||||
|
||||
// clean up static objects that may have been cached
|
||||
static void Shutdown();
|
||||
|
||||
protected:
|
||||
CTFontRef mCTFont;
|
||||
|
||||
// attributes for shaping text with LTR or RTL directionality
|
||||
CFDictionaryRef mAttributesDictLTR;
|
||||
CFDictionaryRef mAttributesDictRTL;
|
||||
|
||||
nsresult SetGlyphsFromRun(gfxShapedText *aShapedText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
CTRunRef aCTRun,
|
||||
int32_t aStringOffset);
|
||||
|
||||
CTFontRef CreateCTFontWithFeatures(CGFloat aSize,
|
||||
CTFontDescriptorRef aDescriptor);
|
||||
|
||||
CFDictionaryRef CreateAttrDict(bool aRightToLeft);
|
||||
CFDictionaryRef CreateAttrDictWithoutDirection();
|
||||
|
||||
static CTFontDescriptorRef
|
||||
CreateFontFeaturesDescriptor(const std::pair<SInt16,SInt16> aFeatures[],
|
||||
size_t aCount);
|
||||
|
||||
static CTFontDescriptorRef GetDefaultFeaturesDescriptor();
|
||||
static CTFontDescriptorRef GetDisableLigaturesDescriptor();
|
||||
static CTFontDescriptorRef GetIndicFeaturesDescriptor();
|
||||
static CTFontDescriptorRef GetIndicDisableLigaturesDescriptor();
|
||||
|
||||
// cached font descriptor, created the first time it's needed
|
||||
static CTFontDescriptorRef sDefaultFeaturesDescriptor;
|
||||
|
||||
// cached descriptor for adding disable-ligatures setting to a font
|
||||
static CTFontDescriptorRef sDisableLigaturesDescriptor;
|
||||
|
||||
// feature descriptors for buggy Indic AAT font workaround
|
||||
static CTFontDescriptorRef sIndicFeaturesDescriptor;
|
||||
static CTFontDescriptorRef sIndicDisableLigaturesDescriptor;
|
||||
};
|
||||
|
||||
#endif /* GFX_CORETEXTSHAPER_H */
|
||||
|
|
@ -379,24 +379,14 @@ gfxFontUtils::ReadCMAPTableFormat14(const uint8_t *aBuf, uint32_t aLength,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// For fonts with two format-4 tables, the first one (Unicode platform) is preferred on the Mac;
|
||||
// on other platforms we allow the Microsoft-platform subtable to replace it.
|
||||
// For fonts with two format-4 tables, we allow the first one (Unicode platform)
|
||||
// to be replaced by the Microsoft-platform subtable.
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define acceptableFormat4(p,e,k) (((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDMicrosoft && !(k)) || \
|
||||
((p) == PLATFORM_ID_UNICODE))
|
||||
#define acceptableFormat4(p,e,k) (((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDMicrosoft) || \
|
||||
((p) == PLATFORM_ID_UNICODE))
|
||||
|
||||
#define acceptableUCS4Encoding(p, e, k) \
|
||||
(((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDUCS4ForMicrosoftPlatform) && (k) != 12 || \
|
||||
((p) == PLATFORM_ID_UNICODE && \
|
||||
((e) != EncodingIDUVSForUnicodePlatform)))
|
||||
#else
|
||||
#define acceptableFormat4(p,e,k) (((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDMicrosoft) || \
|
||||
((p) == PLATFORM_ID_UNICODE))
|
||||
|
||||
#define acceptableUCS4Encoding(p, e, k) \
|
||||
#define acceptableUCS4Encoding(p, e, k) \
|
||||
((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDUCS4ForMicrosoftPlatform)
|
||||
#endif
|
||||
|
||||
#define acceptablePlatform(p) ((p) == PLATFORM_ID_UNICODE || (p) == PLATFORM_ID_MICROSOFT)
|
||||
#define isSymbol(p,e) ((p) == PLATFORM_ID_MICROSOFT && (e) == EncodingIDSymbol)
|
||||
|
|
@ -1230,13 +1220,8 @@ gfxFontUtils::GetFamilyNameFromTable(hb_blob_t *aNameTable,
|
|||
}
|
||||
|
||||
enum {
|
||||
#if defined(XP_MACOSX)
|
||||
CANONICAL_LANG_ID = gfxFontUtils::LANG_ID_MAC_ENGLISH,
|
||||
PLATFORM_ID = gfxFontUtils::PLATFORM_ID_MAC
|
||||
#else
|
||||
CANONICAL_LANG_ID = gfxFontUtils::LANG_ID_MICROSOFT_EN_US,
|
||||
PLATFORM_ID = gfxFontUtils::PLATFORM_ID_MICROSOFT
|
||||
#endif
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
|
@ -1277,22 +1262,6 @@ gfxFontUtils::ReadCanonicalName(const char *aNameData, uint32_t aDataLen,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// may be dealing with font that only has Microsoft name entries
|
||||
if (names.Length() == 0) {
|
||||
rv = ReadNames(aNameData, aDataLen, aNameID, LANG_ID_MICROSOFT_EN_US,
|
||||
PLATFORM_ID_MICROSOFT, names);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// getting really desperate now, take anything!
|
||||
if (names.Length() == 0) {
|
||||
rv = ReadNames(aNameData, aDataLen, aNameID, LANG_ALL,
|
||||
PLATFORM_ID_MICROSOFT, names);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// return the first name (99.9% of the time names will
|
||||
// contain a single English name)
|
||||
if (names.Length()) {
|
||||
|
|
|
|||
|
|
@ -1,475 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gfxMacFont.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "gfxCoreTextShaper.h"
|
||||
#include <algorithm>
|
||||
#include "gfxPlatformMac.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxFontUtils.h"
|
||||
#include "gfxMacPlatformFontList.h"
|
||||
#include "gfxFontConstants.h"
|
||||
#include "gfxTextRun.h"
|
||||
|
||||
#include "cairo-quartz.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
|
||||
bool aNeedsBold)
|
||||
: gfxFont(aFontEntry, aFontStyle),
|
||||
mCGFont(nullptr),
|
||||
mCTFont(nullptr),
|
||||
mFontFace(nullptr)
|
||||
{
|
||||
mApplySyntheticBold = aNeedsBold;
|
||||
|
||||
mCGFont = aFontEntry->GetFontRef();
|
||||
if (!mCGFont) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// InitMetrics will handle the sizeAdjust factor and set mAdjustedSize
|
||||
InitMetrics();
|
||||
if (!mIsValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFontFace = cairo_quartz_font_face_create_for_cgfont(mCGFont);
|
||||
|
||||
cairo_status_t cairoerr = cairo_font_face_status(mFontFace);
|
||||
if (cairoerr != CAIRO_STATUS_SUCCESS) {
|
||||
mIsValid = false;
|
||||
#ifdef DEBUG
|
||||
char warnBuf[1024];
|
||||
SprintfLiteral(warnBuf,
|
||||
"Failed to create Cairo font face: %s status: %d",
|
||||
NS_ConvertUTF16toUTF8(GetName()).get(), cairoerr);
|
||||
NS_WARNING(warnBuf);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_matrix_t sizeMatrix, ctm;
|
||||
cairo_matrix_init_identity(&ctm);
|
||||
cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
|
||||
|
||||
// synthetic oblique by skewing via the font matrix
|
||||
bool needsOblique = mFontEntry != nullptr &&
|
||||
mFontEntry->IsUpright() &&
|
||||
mStyle.style != NS_FONT_STYLE_NORMAL &&
|
||||
mStyle.allowSyntheticStyle;
|
||||
|
||||
if (needsOblique) {
|
||||
cairo_matrix_t style;
|
||||
cairo_matrix_init(&style,
|
||||
1, //xx
|
||||
0, //yx
|
||||
-1 * OBLIQUE_SKEW_FACTOR, //xy
|
||||
1, //yy
|
||||
0, //x0
|
||||
0); //y0
|
||||
cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
|
||||
}
|
||||
|
||||
cairo_font_options_t *fontOptions = cairo_font_options_create();
|
||||
|
||||
// turn off font anti-aliasing based on user pref setting
|
||||
if (mAdjustedSize <=
|
||||
(gfxFloat)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
|
||||
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_NONE);
|
||||
mAntialiasOption = kAntialiasNone;
|
||||
} else if (mStyle.useGrayscaleAntialiasing) {
|
||||
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY);
|
||||
mAntialiasOption = kAntialiasGrayscale;
|
||||
}
|
||||
|
||||
mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm,
|
||||
fontOptions);
|
||||
cairo_font_options_destroy(fontOptions);
|
||||
|
||||
cairoerr = cairo_scaled_font_status(mScaledFont);
|
||||
if (cairoerr != CAIRO_STATUS_SUCCESS) {
|
||||
mIsValid = false;
|
||||
#ifdef DEBUG
|
||||
char warnBuf[1024];
|
||||
SprintfLiteral(warnBuf, "Failed to create scaled font: %s status: %d",
|
||||
NS_ConvertUTF16toUTF8(GetName()).get(), cairoerr);
|
||||
NS_WARNING(warnBuf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
gfxMacFont::~gfxMacFont()
|
||||
{
|
||||
if (mCTFont) {
|
||||
::CFRelease(mCTFont);
|
||||
}
|
||||
if (mScaledFont) {
|
||||
cairo_scaled_font_destroy(mScaledFont);
|
||||
}
|
||||
if (mFontFace) {
|
||||
cairo_font_face_destroy(mFontFace);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gfxMacFont::ShapeText(DrawTarget *aDrawTarget,
|
||||
const char16_t *aText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Script aScript,
|
||||
bool aVertical,
|
||||
gfxShapedText *aShapedText)
|
||||
{
|
||||
if (!mIsValid) {
|
||||
NS_WARNING("invalid font! expect incorrect text rendering");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Currently, we don't support vertical shaping via CoreText,
|
||||
// so we ignore RequiresAATLayout if vertical is requested.
|
||||
if (static_cast<MacOSFontEntry*>(GetFontEntry())->RequiresAATLayout() &&
|
||||
!aVertical) {
|
||||
if (!mCoreTextShaper) {
|
||||
mCoreTextShaper = MakeUnique<gfxCoreTextShaper>(this);
|
||||
}
|
||||
if (mCoreTextShaper->ShapeText(aDrawTarget, aText, aOffset, aLength,
|
||||
aScript, aVertical, aShapedText)) {
|
||||
PostShapingFixup(aDrawTarget, aText, aOffset,
|
||||
aLength, aVertical, aShapedText);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aShapedText);
|
||||
}
|
||||
|
||||
bool
|
||||
gfxMacFont::SetupCairoFont(DrawTarget* aDrawTarget)
|
||||
{
|
||||
if (cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return false;
|
||||
}
|
||||
cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), mScaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxFont::RunMetrics
|
||||
gfxMacFont::Measure(const gfxTextRun *aTextRun,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget *aRefDrawTarget,
|
||||
Spacing *aSpacing,
|
||||
uint16_t aOrientation)
|
||||
{
|
||||
gfxFont::RunMetrics metrics =
|
||||
gfxFont::Measure(aTextRun, aStart, aEnd,
|
||||
aBoundingBoxType, aRefDrawTarget, aSpacing,
|
||||
aOrientation);
|
||||
|
||||
// if aBoundingBoxType is not TIGHT_HINTED_OUTLINE_EXTENTS then we need to add
|
||||
// a pixel column each side of the bounding box in case of antialiasing "bleed"
|
||||
if (aBoundingBoxType != TIGHT_HINTED_OUTLINE_EXTENTS &&
|
||||
metrics.mBoundingBox.width > 0) {
|
||||
metrics.mBoundingBox.x -= aTextRun->GetAppUnitsPerDevUnit();
|
||||
metrics.mBoundingBox.width += aTextRun->GetAppUnitsPerDevUnit() * 2;
|
||||
}
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::InitMetrics()
|
||||
{
|
||||
mIsValid = false;
|
||||
::memset(&mMetrics, 0, sizeof(mMetrics));
|
||||
|
||||
uint32_t upem = 0;
|
||||
|
||||
// try to get unitsPerEm from sfnt head table, to avoid calling CGFont
|
||||
// if possible (bug 574368) and because CGFontGetUnitsPerEm does not
|
||||
// return the true value for OpenType/CFF fonts (it normalizes to 1000,
|
||||
// which then leads to metrics errors when we read the 'hmtx' table to
|
||||
// get glyph advances for HarfBuzz, see bug 580863)
|
||||
CFDataRef headData =
|
||||
::CGFontCopyTableForTag(mCGFont, TRUETYPE_TAG('h','e','a','d'));
|
||||
if (headData) {
|
||||
if (size_t(::CFDataGetLength(headData)) >= sizeof(HeadTable)) {
|
||||
const HeadTable *head =
|
||||
reinterpret_cast<const HeadTable*>(::CFDataGetBytePtr(headData));
|
||||
upem = head->unitsPerEm;
|
||||
}
|
||||
::CFRelease(headData);
|
||||
}
|
||||
if (!upem) {
|
||||
upem = ::CGFontGetUnitsPerEm(mCGFont);
|
||||
}
|
||||
|
||||
if (upem < 16 || upem > 16384) {
|
||||
// See http://www.microsoft.com/typography/otspec/head.htm
|
||||
#ifdef DEBUG
|
||||
char warnBuf[1024];
|
||||
SprintfLiteral(warnBuf,
|
||||
"Bad font metrics for: %s (invalid unitsPerEm value)",
|
||||
NS_ConvertUTF16toUTF8(mFontEntry->Name()).get());
|
||||
NS_WARNING(warnBuf);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
mAdjustedSize = std::max(mStyle.size, 1.0);
|
||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
||||
|
||||
// For CFF fonts, when scaling values read from CGFont* APIs, we need to
|
||||
// use CG's idea of unitsPerEm, which may differ from the "true" value in
|
||||
// the head table of the font (see bug 580863)
|
||||
gfxFloat cgConvFactor;
|
||||
if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
|
||||
cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
|
||||
} else {
|
||||
cgConvFactor = mFUnitsConvFactor;
|
||||
}
|
||||
|
||||
// Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
|
||||
// platform APIs. The InitMetrics...() functions will set mIsValid on success.
|
||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
|
||||
InitMetricsFromPlatform();
|
||||
}
|
||||
if (!mIsValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mMetrics.xHeight == 0.0) {
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
|
||||
if (mMetrics.capHeight == 0.0) {
|
||||
mMetrics.capHeight = ::CGFontGetCapHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
|
||||
if (mStyle.sizeAdjust > 0.0 && mStyle.size > 0.0 &&
|
||||
mMetrics.xHeight > 0.0) {
|
||||
// apply font-size-adjust, and recalculate metrics
|
||||
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
|
||||
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
|
||||
mFUnitsConvFactor = mAdjustedSize / upem;
|
||||
if (static_cast<MacOSFontEntry*>(mFontEntry.get())->IsCFF()) {
|
||||
cgConvFactor = mAdjustedSize / ::CGFontGetUnitsPerEm(mCGFont);
|
||||
} else {
|
||||
cgConvFactor = mFUnitsConvFactor;
|
||||
}
|
||||
mMetrics.xHeight = 0.0;
|
||||
if (!InitMetricsFromSfntTables(mMetrics) &&
|
||||
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
|
||||
InitMetricsFromPlatform();
|
||||
}
|
||||
if (!mIsValid) {
|
||||
// this shouldn't happen, as we succeeded earlier before applying
|
||||
// the size-adjust factor! But check anyway, for paranoia's sake.
|
||||
return;
|
||||
}
|
||||
if (mMetrics.xHeight == 0.0) {
|
||||
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * cgConvFactor;
|
||||
}
|
||||
}
|
||||
|
||||
// Once we reach here, we've got basic metrics and set mIsValid = TRUE;
|
||||
// there should be no further points of actual failure in InitMetrics().
|
||||
// (If one is introduced, be sure to reset mIsValid to FALSE!)
|
||||
|
||||
mMetrics.emHeight = mAdjustedSize;
|
||||
|
||||
// Measure/calculate additional metrics, independent of whether we used
|
||||
// the tables directly or ATS metrics APIs
|
||||
|
||||
CFDataRef cmap =
|
||||
::CGFontCopyTableForTag(mCGFont, TRUETYPE_TAG('c','m','a','p'));
|
||||
|
||||
uint32_t glyphID;
|
||||
if (mMetrics.aveCharWidth <= 0) {
|
||||
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID,
|
||||
cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
// we didn't find 'x', so use maxAdvance rather than zero
|
||||
mMetrics.aveCharWidth = mMetrics.maxAdvance;
|
||||
}
|
||||
}
|
||||
if (IsSyntheticBold()) {
|
||||
mMetrics.aveCharWidth += GetSyntheticBoldOffset();
|
||||
mMetrics.maxAdvance += GetSyntheticBoldOffset();
|
||||
}
|
||||
|
||||
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID, cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
// no space glyph?!
|
||||
mMetrics.spaceWidth = mMetrics.aveCharWidth;
|
||||
}
|
||||
mSpaceGlyph = glyphID;
|
||||
|
||||
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID,
|
||||
cgConvFactor);
|
||||
if (glyphID == 0) {
|
||||
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
||||
}
|
||||
|
||||
if (cmap) {
|
||||
::CFRelease(cmap);
|
||||
}
|
||||
|
||||
CalculateDerivedMetrics(mMetrics);
|
||||
|
||||
SanitizeMetrics(&mMetrics, mFontEntry->mIsBadUnderlineFont);
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "Font: %p (%s) size: %f\n", this,
|
||||
NS_ConvertUTF16toUTF8(GetName()).get(), mStyle.size);
|
||||
// fprintf (stderr, " fbounds.origin.x %f y %f size.width %f height %f\n", fbounds.origin.x, fbounds.origin.y, fbounds.size.width, fbounds.size.height);
|
||||
fprintf (stderr, " emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
|
||||
fprintf (stderr, " maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
|
||||
fprintf (stderr, " internalLeading: %f externalLeading: %f\n", mMetrics.internalLeading, mMetrics.externalLeading);
|
||||
fprintf (stderr, " spaceWidth: %f aveCharWidth: %f xHeight: %f capHeight: %f\n", mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.xHeight, mMetrics.capHeight);
|
||||
fprintf (stderr, " uOff: %f uSize: %f stOff: %f stSize: %f\n", mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
gfxMacFont::GetCharWidth(CFDataRef aCmap, char16_t aUniChar,
|
||||
uint32_t *aGlyphID, gfxFloat aConvFactor)
|
||||
{
|
||||
CGGlyph glyph = 0;
|
||||
|
||||
if (aCmap) {
|
||||
glyph = gfxFontUtils::MapCharToGlyph(::CFDataGetBytePtr(aCmap),
|
||||
::CFDataGetLength(aCmap),
|
||||
aUniChar);
|
||||
}
|
||||
|
||||
if (aGlyphID) {
|
||||
*aGlyphID = glyph;
|
||||
}
|
||||
|
||||
if (glyph) {
|
||||
int advance;
|
||||
if (::CGFontGetGlyphAdvances(mCGFont, &glyph, 1, &advance)) {
|
||||
return advance * aConvFactor;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
gfxMacFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID)
|
||||
{
|
||||
if (!mCTFont) {
|
||||
mCTFont = ::CTFontCreateWithGraphicsFont(mCGFont, mAdjustedSize,
|
||||
nullptr, nullptr);
|
||||
if (!mCTFont) { // shouldn't happen, but let's be safe
|
||||
NS_WARNING("failed to create CTFontRef to measure glyph width");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CGSize advance;
|
||||
::CTFontGetAdvancesForGlyphs(mCTFont, kCTFontDefaultOrientation, &aGID,
|
||||
&advance, 1);
|
||||
return advance.width * 0x10000;
|
||||
}
|
||||
|
||||
// Try to initialize font metrics via platform APIs (CG/CT),
|
||||
// and set mIsValid = TRUE on success.
|
||||
// We ONLY call this for local (platform) fonts that are not sfnt format;
|
||||
// for sfnts, including ALL downloadable fonts, we prefer to use
|
||||
// InitMetricsFromSfntTables and avoid platform APIs.
|
||||
void
|
||||
gfxMacFont::InitMetricsFromPlatform()
|
||||
{
|
||||
CTFontRef ctFont = ::CTFontCreateWithGraphicsFont(mCGFont,
|
||||
mAdjustedSize,
|
||||
nullptr, nullptr);
|
||||
if (!ctFont) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMetrics.underlineOffset = ::CTFontGetUnderlinePosition(ctFont);
|
||||
mMetrics.underlineSize = ::CTFontGetUnderlineThickness(ctFont);
|
||||
|
||||
mMetrics.externalLeading = ::CTFontGetLeading(ctFont);
|
||||
|
||||
mMetrics.maxAscent = ::CTFontGetAscent(ctFont);
|
||||
mMetrics.maxDescent = ::CTFontGetDescent(ctFont);
|
||||
|
||||
// this is not strictly correct, but neither CTFont nor CGFont seems to
|
||||
// provide maxAdvance, unless we were to iterate over all the glyphs
|
||||
// (which isn't worth the cost here)
|
||||
CGRect r = ::CTFontGetBoundingBox(ctFont);
|
||||
mMetrics.maxAdvance = r.size.width;
|
||||
|
||||
// aveCharWidth is also not provided, so leave it at zero
|
||||
// (fallback code in gfxMacFont::InitMetrics will then try measuring 'x');
|
||||
// this could lead to less-than-"perfect" text field sizing when width is
|
||||
// specified as a number of characters, and the font in use is a non-sfnt
|
||||
// legacy font, but that's a sufficiently obscure edge case that we can
|
||||
// ignore the potential discrepancy.
|
||||
mMetrics.aveCharWidth = 0;
|
||||
|
||||
mMetrics.xHeight = ::CTFontGetXHeight(ctFont);
|
||||
mMetrics.capHeight = ::CTFontGetCapHeight(ctFont);
|
||||
|
||||
::CFRelease(ctFont);
|
||||
|
||||
mIsValid = true;
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
gfxMacFont::GetScaledFont(DrawTarget *aTarget)
|
||||
{
|
||||
if (!mAzureScaledFont) {
|
||||
NativeFont nativeFont;
|
||||
nativeFont.mType = NativeFontType::MAC_FONT_FACE;
|
||||
nativeFont.mFont = GetCGFontRef();
|
||||
mAzureScaledFont = mozilla::gfx::Factory::CreateScaledFontWithCairo(nativeFont, GetAdjustedSize(), mScaledFont);
|
||||
}
|
||||
|
||||
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
|
||||
gfxMacFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams)
|
||||
{
|
||||
if (aRunParams) {
|
||||
return mozilla::gfx::Factory::CreateCGGlyphRenderingOptions(aRunParams->fontSmoothingBGColor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
gfxFont::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
// mCGFont is shared with the font entry, so not counted here;
|
||||
// and we don't have APIs to measure the cairo mFontFace object
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_MACFONT_H
|
||||
#define GFX_MACFONT_H
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "gfxFont.h"
|
||||
#include "cairo.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
class MacOSFontEntry;
|
||||
|
||||
class gfxMacFont : public gfxFont
|
||||
{
|
||||
public:
|
||||
gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
|
||||
bool aNeedsBold);
|
||||
|
||||
virtual ~gfxMacFont();
|
||||
|
||||
CGFontRef GetCGFontRef() const { return mCGFont; }
|
||||
|
||||
/* overrides for the pure virtual methods in gfxFont */
|
||||
virtual uint32_t GetSpaceGlyph() override {
|
||||
return mSpaceGlyph;
|
||||
}
|
||||
|
||||
virtual bool SetupCairoFont(DrawTarget* aDrawTarget) override;
|
||||
|
||||
/* override Measure to add padding for antialiasing */
|
||||
virtual RunMetrics Measure(const gfxTextRun *aTextRun,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
BoundingBoxType aBoundingBoxType,
|
||||
DrawTarget *aDrawTargetForTightBoundingBox,
|
||||
Spacing *aSpacing,
|
||||
uint16_t aOrientation) override;
|
||||
|
||||
// We need to provide hinted (non-linear) glyph widths if using a font
|
||||
// with embedded color bitmaps (Apple Color Emoji), as Core Text renders
|
||||
// the glyphs with non-linear scaling at small pixel sizes.
|
||||
virtual bool ProvidesGlyphWidths() const override {
|
||||
return mFontEntry->HasFontTable(TRUETYPE_TAG('s','b','i','x'));
|
||||
}
|
||||
|
||||
virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget,
|
||||
uint16_t aGID) override;
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::ScaledFont>
|
||||
GetScaledFont(mozilla::gfx::DrawTarget *aTarget) override;
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::GlyphRenderingOptions>
|
||||
GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override;
|
||||
|
||||
virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const override;
|
||||
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const override;
|
||||
|
||||
virtual FontType GetType() const override { return FONT_TYPE_MAC; }
|
||||
|
||||
protected:
|
||||
virtual const Metrics& GetHorizontalMetrics() override {
|
||||
return mMetrics;
|
||||
}
|
||||
|
||||
// override to prefer CoreText shaping with fonts that depend on AAT
|
||||
virtual bool ShapeText(DrawTarget *aDrawTarget,
|
||||
const char16_t *aText,
|
||||
uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
Script aScript,
|
||||
bool aVertical,
|
||||
gfxShapedText *aShapedText) override;
|
||||
|
||||
void InitMetrics();
|
||||
void InitMetricsFromPlatform();
|
||||
|
||||
// Get width and glyph ID for a character; uses aConvFactor
|
||||
// to convert font units as returned by CG to actual dimensions
|
||||
gfxFloat GetCharWidth(CFDataRef aCmap, char16_t aUniChar,
|
||||
uint32_t *aGlyphID, gfxFloat aConvFactor);
|
||||
|
||||
// a weak reference to the CoreGraphics font: this is owned by the
|
||||
// MacOSFontEntry, it is not retained or released by gfxMacFont
|
||||
CGFontRef mCGFont;
|
||||
|
||||
// a Core Text font reference, created only if we're using CT to measure
|
||||
// glyph widths; otherwise null.
|
||||
CTFontRef mCTFont;
|
||||
|
||||
cairo_font_face_t *mFontFace;
|
||||
|
||||
mozilla::UniquePtr<gfxFontShaper> mCoreTextShaper;
|
||||
|
||||
Metrics mMetrics;
|
||||
uint32_t mSpaceGlyph;
|
||||
};
|
||||
|
||||
#endif /* GFX_MACFONT_H */
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef gfxMacPlatformFontList_H_
|
||||
#define gfxMacPlatformFontList_H_
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
#include "gfxPlatformFontList.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxPlatformMac.h"
|
||||
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
class gfxMacPlatformFontList;
|
||||
|
||||
// a single member of a font family (i.e. a single face, such as Times Italic)
|
||||
class MacOSFontEntry : public gfxFontEntry
|
||||
{
|
||||
public:
|
||||
friend class gfxMacPlatformFontList;
|
||||
|
||||
MacOSFontEntry(const nsAString& aPostscriptName, int32_t aWeight,
|
||||
bool aIsStandardFace = false,
|
||||
double aSizeHint = 0.0);
|
||||
|
||||
// for use with data fonts
|
||||
MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef,
|
||||
uint16_t aWeight, uint16_t aStretch, uint8_t aStyle,
|
||||
bool aIsDataUserFont, bool aIsLocal);
|
||||
|
||||
virtual ~MacOSFontEntry() {
|
||||
::CGFontRelease(mFontRef);
|
||||
}
|
||||
|
||||
virtual CGFontRef GetFontRef();
|
||||
|
||||
// override gfxFontEntry table access function to bypass table cache,
|
||||
// use CGFontRef API to get direct access to system font data
|
||||
virtual hb_blob_t *GetFontTable(uint32_t aTag) override;
|
||||
|
||||
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontListSizes* aSizes) const override;
|
||||
|
||||
nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override;
|
||||
|
||||
bool RequiresAATLayout() const { return mRequiresAAT; }
|
||||
|
||||
bool IsCFF();
|
||||
|
||||
protected:
|
||||
virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) override;
|
||||
|
||||
virtual bool HasFontTable(uint32_t aTableTag) override;
|
||||
|
||||
static void DestroyBlobFunc(void* aUserData);
|
||||
|
||||
CGFontRef mFontRef; // owning reference to the CGFont, released on destruction
|
||||
|
||||
double mSizeHint;
|
||||
|
||||
bool mFontRefInitialized;
|
||||
bool mRequiresAAT;
|
||||
bool mIsCFF;
|
||||
bool mIsCFFInitialized;
|
||||
nsTHashtable<nsUint32HashKey> mAvailableTables;
|
||||
};
|
||||
|
||||
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
||||
public:
|
||||
static gfxMacPlatformFontList* PlatformFontList() {
|
||||
return static_cast<gfxMacPlatformFontList*>(sPlatformFontList);
|
||||
}
|
||||
|
||||
static int32_t AppleWeightToCSSWeight(int32_t aAppleWeight);
|
||||
|
||||
bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) override;
|
||||
|
||||
gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
int16_t aStretch,
|
||||
uint8_t aStyle) override;
|
||||
|
||||
gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
int16_t aStretch,
|
||||
uint8_t aStyle,
|
||||
const uint8_t* aFontData,
|
||||
uint32_t aLength) override;
|
||||
|
||||
bool FindAndAddFamilies(const nsAString& aFamily,
|
||||
nsTArray<gfxFontFamily*>* aOutput,
|
||||
gfxFontStyle* aStyle = nullptr,
|
||||
gfxFloat aDevToCssSize = 1.0) override;
|
||||
|
||||
// lookup the system font for a particular system font type and set
|
||||
// the name and style characteristics
|
||||
void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
|
||||
nsAString& aSystemFontName,
|
||||
gfxFontStyle &aFontStyle,
|
||||
float aDevPixPerCSSPixel);
|
||||
|
||||
protected:
|
||||
virtual gfxFontFamily*
|
||||
GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
|
||||
|
||||
private:
|
||||
friend class gfxPlatformMac;
|
||||
|
||||
gfxMacPlatformFontList();
|
||||
virtual ~gfxMacPlatformFontList();
|
||||
|
||||
// initialize font lists
|
||||
virtual nsresult InitFontListForPlatform() override;
|
||||
|
||||
// special case font faces treated as font families (set via prefs)
|
||||
void InitSingleFaceList();
|
||||
|
||||
// initialize system fonts
|
||||
void InitSystemFontNames();
|
||||
|
||||
// helper function to lookup in both hidden system fonts and normal fonts
|
||||
gfxFontFamily* FindSystemFontFamily(const nsAString& aFamily);
|
||||
|
||||
static void RegisteredFontsChangedNotificationCallback(CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo);
|
||||
|
||||
// attempt to use platform-specific fallback for the given character
|
||||
// return null if no usable result found
|
||||
gfxFontEntry*
|
||||
PlatformGlobalFontFallback(const uint32_t aCh,
|
||||
Script aRunScript,
|
||||
const gfxFontStyle* aMatchStyle,
|
||||
gfxFontFamily** aMatchedFamily) override;
|
||||
|
||||
bool UsesSystemFallback() override { return true; }
|
||||
|
||||
already_AddRefed<FontInfoData> CreateFontInfoData() override;
|
||||
|
||||
// Add the specified family to mSystemFontFamilies or mFontFamilies.
|
||||
// Ideally we'd use NSString* instead of CFStringRef here, but this header
|
||||
// file is included in .cpp files, so we can't use objective C classes here.
|
||||
// But CFStringRef and NSString* are the same thing anyway (they're
|
||||
// toll-free bridged).
|
||||
void AddFamily(CFStringRef aFamily);
|
||||
|
||||
#ifdef MOZ_BUNDLED_FONTS
|
||||
void ActivateBundledFonts();
|
||||
#endif
|
||||
|
||||
enum {
|
||||
kATSGenerationInitial = -1
|
||||
};
|
||||
|
||||
// default font for use with system-wide font fallback
|
||||
CTFontRef mDefaultFont;
|
||||
|
||||
// hidden system fonts used within UI elements, there may be a whole set
|
||||
// for different locales (e.g. .Helvetica Neue UI, .SF NS Text)
|
||||
FontFamilyTable mSystemFontFamilies;
|
||||
|
||||
// font families that -apple-system maps to
|
||||
// Pre-10.11 this was always a single font family, such as Lucida Grande
|
||||
// or Helvetica Neue. For OSX 10.11, Apple uses pair of families
|
||||
// for the UI, one for text sizes and another for display sizes
|
||||
bool mUseSizeSensitiveSystemFont;
|
||||
nsString mSystemTextFontFamilyName;
|
||||
nsString mSystemDisplayFontFamilyName; // only used on OSX 10.11
|
||||
};
|
||||
|
||||
#endif /* gfxMacPlatformFontList_H_ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -37,9 +37,6 @@
|
|||
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "gfxPlatformMac.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
#elif defined(MOZ_WIDGET_GTK)
|
||||
#include "gfxPlatformGtk.h"
|
||||
#elif defined(ANDROID)
|
||||
|
|
@ -579,8 +576,6 @@ gfxPlatform::Init()
|
|||
|
||||
#if defined(XP_WIN)
|
||||
gPlatform = new gfxWindowsPlatform;
|
||||
#elif defined(XP_MACOSX)
|
||||
gPlatform = new gfxPlatformMac;
|
||||
#elif defined(MOZ_WIDGET_GTK)
|
||||
gPlatform = new gfxPlatformGtk;
|
||||
#elif defined(ANDROID)
|
||||
|
|
@ -2157,7 +2152,7 @@ bool
|
|||
gfxPlatform::AccelerateLayersByDefault()
|
||||
{
|
||||
// Note: add any new platform defines here that should get HWA by default.
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_UIKIT)
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_UIKIT)
|
||||
return true;
|
||||
#elif defined(MOZ_GL_PROVIDER)
|
||||
// GL provider manually declared
|
||||
|
|
|
|||
|
|
@ -1,617 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gfxPlatformMac.h"
|
||||
|
||||
#include "gfxQuartzSurface.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
|
||||
#include "gfxMacPlatformFontList.h"
|
||||
#include "gfxMacFont.h"
|
||||
#include "gfxCoreTextShaper.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
#include "nsUnicodeProperties.h"
|
||||
#include "qcms.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <CoreVideo/CoreVideo.h>
|
||||
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "VsyncSource.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::unicode;
|
||||
|
||||
// cribbed from CTFontManager.h
|
||||
enum {
|
||||
kAutoActivationDisabled = 1
|
||||
};
|
||||
typedef uint32_t AutoActivationSetting;
|
||||
|
||||
// bug 567552 - disable auto-activation of fonts
|
||||
|
||||
static void
|
||||
DisableFontActivation()
|
||||
{
|
||||
// get the main bundle identifier
|
||||
CFBundleRef mainBundle = ::CFBundleGetMainBundle();
|
||||
CFStringRef mainBundleID = nullptr;
|
||||
|
||||
if (mainBundle) {
|
||||
mainBundleID = ::CFBundleGetIdentifier(mainBundle);
|
||||
}
|
||||
|
||||
// bug 969388 and bug 922590 - mainBundlID as null is sometimes problematic
|
||||
if (!mainBundleID) {
|
||||
NS_WARNING("missing bundle ID, packaging set up incorrectly");
|
||||
return;
|
||||
}
|
||||
|
||||
// if possible, fetch CTFontManagerSetAutoActivationSetting
|
||||
void (*CTFontManagerSetAutoActivationSettingPtr)
|
||||
(CFStringRef, AutoActivationSetting);
|
||||
CTFontManagerSetAutoActivationSettingPtr =
|
||||
(void (*)(CFStringRef, AutoActivationSetting))
|
||||
dlsym(RTLD_DEFAULT, "CTFontManagerSetAutoActivationSetting");
|
||||
|
||||
// bug 567552 - disable auto-activation of fonts
|
||||
if (CTFontManagerSetAutoActivationSettingPtr) {
|
||||
CTFontManagerSetAutoActivationSettingPtr(mainBundleID,
|
||||
kAutoActivationDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
gfxPlatformMac::gfxPlatformMac()
|
||||
{
|
||||
DisableFontActivation();
|
||||
mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
|
||||
|
||||
uint32_t canvasMask = BackendTypeBit(BackendType::SKIA);
|
||||
uint32_t contentMask = BackendTypeBit(BackendType::SKIA);
|
||||
InitBackendPrefs(canvasMask, BackendType::SKIA,
|
||||
contentMask, BackendType::SKIA);
|
||||
|
||||
// XXX: Bug 1036682 - we run out of fds on Mac when using tiled layers because
|
||||
// with 256x256 tiles we can easily hit the soft limit of 800 when using double
|
||||
// buffered tiles in e10s, so let's bump the soft limit to the hard limit for the OS
|
||||
// up to a new cap of OPEN_MAX.
|
||||
struct rlimit limits;
|
||||
if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
|
||||
limits.rlim_cur = std::min(rlim_t(OPEN_MAX), limits.rlim_max);
|
||||
if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
|
||||
NS_WARNING("Unable to bump RLIMIT_NOFILE to the maximum number on this OS");
|
||||
}
|
||||
}
|
||||
|
||||
MacIOSurfaceLib::LoadLibrary();
|
||||
}
|
||||
|
||||
gfxPlatformMac::~gfxPlatformMac()
|
||||
{
|
||||
gfxCoreTextShaper::Shutdown();
|
||||
}
|
||||
|
||||
gfxPlatformFontList*
|
||||
gfxPlatformMac::CreatePlatformFontList()
|
||||
{
|
||||
gfxPlatformFontList* list = new gfxMacPlatformFontList();
|
||||
if (NS_SUCCEEDED(list->InitFontList())) {
|
||||
return list;
|
||||
}
|
||||
gfxPlatformFontList::Shutdown();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxPlatformMac::CreateOffscreenSurface(const IntSize& aSize,
|
||||
gfxImageFormat aFormat)
|
||||
{
|
||||
if (!Factory::AllowedSurfaceSize(aSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<gfxASurface> newSurface =
|
||||
new gfxQuartzSurface(aSize, aFormat);
|
||||
return newSurface.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
gfxPlatformMac::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
|
||||
{
|
||||
gfxMacFont *font = static_cast<gfxMacFont*>(aFont);
|
||||
return font->GetScaledFont(aTarget);
|
||||
}
|
||||
|
||||
gfxFontGroup *
|
||||
gfxPlatformMac::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatformMac::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
|
||||
{
|
||||
// check for strange format flags
|
||||
NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
|
||||
"strange font format hint set");
|
||||
|
||||
// accept supported formats
|
||||
if (aFormatFlags & (gfxUserFontSet::FLAG_FORMATS_COMMON |
|
||||
gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// reject all other formats, known and unknown
|
||||
if (aFormatFlags != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no format hint set, need to look at data
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char kFontArialUnicodeMS[] = "Arial Unicode MS";
|
||||
static const char kFontAppleBraille[] = "Apple Braille";
|
||||
static const char kFontAppleColorEmoji[] = "Apple Color Emoji";
|
||||
static const char kFontAppleSymbols[] = "Apple Symbols";
|
||||
static const char kFontDevanagariSangamMN[] = "Devanagari Sangam MN";
|
||||
static const char kFontEuphemiaUCAS[] = "Euphemia UCAS";
|
||||
static const char kFontGeneva[] = "Geneva";
|
||||
static const char kFontGeezaPro[] = "Geeza Pro";
|
||||
static const char kFontGujaratiSangamMN[] = "Gujarati Sangam MN";
|
||||
static const char kFontGurmukhiMN[] = "Gurmukhi MN";
|
||||
static const char kFontHiraginoKakuGothic[] = "Hiragino Kaku Gothic ProN";
|
||||
static const char kFontHiraginoSansGB[] = "Hiragino Sans GB";
|
||||
static const char kFontKefa[] = "Kefa";
|
||||
static const char kFontKhmerMN[] = "Khmer MN";
|
||||
static const char kFontLaoMN[] = "Lao MN";
|
||||
static const char kFontLucidaGrande[] = "Lucida Grande";
|
||||
static const char kFontMenlo[] = "Menlo";
|
||||
static const char kFontMicrosoftTaiLe[] = "Microsoft Tai Le";
|
||||
static const char kFontMingLiUExtB[] = "MingLiU-ExtB";
|
||||
static const char kFontMyanmarMN[] = "Myanmar MN";
|
||||
static const char kFontPlantagenetCherokee[] = "Plantagenet Cherokee";
|
||||
static const char kFontSimSunExtB[] = "SimSun-ExtB";
|
||||
static const char kFontSongtiSC[] = "Songti SC";
|
||||
static const char kFontSTHeiti[] = "STHeiti";
|
||||
static const char kFontSTIXGeneral[] = "STIXGeneral";
|
||||
static const char kFontTamilMN[] = "Tamil MN";
|
||||
|
||||
void
|
||||
gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
|
||||
Script aRunScript,
|
||||
nsTArray<const char*>& aFontList)
|
||||
{
|
||||
EmojiPresentation emoji = GetEmojiPresentation(aCh);
|
||||
if (emoji != EmojiPresentation::TextOnly) {
|
||||
if (aNextCh == kVariationSelector16 ||
|
||||
(aNextCh != kVariationSelector15 &&
|
||||
emoji == EmojiPresentation::EmojiDefault)) {
|
||||
// if char is followed by VS16, try for a color emoji glyph
|
||||
aFontList.AppendElement(kFontAppleColorEmoji);
|
||||
}
|
||||
}
|
||||
|
||||
aFontList.AppendElement(kFontLucidaGrande);
|
||||
|
||||
if (!IS_IN_BMP(aCh)) {
|
||||
uint32_t p = aCh >> 16;
|
||||
if (p == 1) {
|
||||
aFontList.AppendElement(kFontAppleSymbols);
|
||||
aFontList.AppendElement(kFontSTIXGeneral);
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
} else if (p == 2) {
|
||||
// OSX installations with MS Office may have these fonts
|
||||
aFontList.AppendElement(kFontMingLiUExtB);
|
||||
aFontList.AppendElement(kFontSimSunExtB);
|
||||
}
|
||||
} else {
|
||||
uint32_t b = (aCh >> 8) & 0xff;
|
||||
|
||||
switch (b) {
|
||||
case 0x03:
|
||||
case 0x05:
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
break;
|
||||
case 0x07:
|
||||
aFontList.AppendElement(kFontGeezaPro);
|
||||
break;
|
||||
case 0x09:
|
||||
aFontList.AppendElement(kFontDevanagariSangamMN);
|
||||
break;
|
||||
case 0x0a:
|
||||
aFontList.AppendElement(kFontGurmukhiMN);
|
||||
aFontList.AppendElement(kFontGujaratiSangamMN);
|
||||
break;
|
||||
case 0x0b:
|
||||
aFontList.AppendElement(kFontTamilMN);
|
||||
break;
|
||||
case 0x0e:
|
||||
aFontList.AppendElement(kFontLaoMN);
|
||||
break;
|
||||
case 0x0f:
|
||||
aFontList.AppendElement(kFontSongtiSC);
|
||||
break;
|
||||
case 0x10:
|
||||
aFontList.AppendElement(kFontMenlo);
|
||||
aFontList.AppendElement(kFontMyanmarMN);
|
||||
break;
|
||||
case 0x13: // Cherokee
|
||||
aFontList.AppendElement(kFontPlantagenetCherokee);
|
||||
aFontList.AppendElement(kFontKefa);
|
||||
break;
|
||||
case 0x14: // Unified Canadian Aboriginal Syllabics
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
aFontList.AppendElement(kFontEuphemiaUCAS);
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
break;
|
||||
case 0x18: // Mongolian, UCAS
|
||||
aFontList.AppendElement(kFontSTHeiti);
|
||||
aFontList.AppendElement(kFontEuphemiaUCAS);
|
||||
break;
|
||||
case 0x19: // Khmer
|
||||
aFontList.AppendElement(kFontKhmerMN);
|
||||
aFontList.AppendElement(kFontMicrosoftTaiLe);
|
||||
break;
|
||||
case 0x1d:
|
||||
case 0x1e:
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
break;
|
||||
case 0x20: // Symbol ranges
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
case 0x2e:
|
||||
aFontList.AppendElement(kFontHiraginoKakuGothic);
|
||||
aFontList.AppendElement(kFontAppleSymbols);
|
||||
aFontList.AppendElement(kFontMenlo);
|
||||
aFontList.AppendElement(kFontSTIXGeneral);
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
aFontList.AppendElement(kFontAppleColorEmoji);
|
||||
break;
|
||||
case 0x2c:
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
break;
|
||||
case 0x2d:
|
||||
aFontList.AppendElement(kFontKefa);
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
break;
|
||||
case 0x28: // Braille
|
||||
aFontList.AppendElement(kFontAppleBraille);
|
||||
break;
|
||||
case 0x31:
|
||||
aFontList.AppendElement(kFontHiraginoSansGB);
|
||||
break;
|
||||
case 0x4d:
|
||||
aFontList.AppendElement(kFontAppleSymbols);
|
||||
break;
|
||||
case 0xa0: // Yi
|
||||
case 0xa1:
|
||||
case 0xa2:
|
||||
case 0xa3:
|
||||
case 0xa4:
|
||||
aFontList.AppendElement(kFontSTHeiti);
|
||||
break;
|
||||
case 0xa6:
|
||||
case 0xa7:
|
||||
aFontList.AppendElement(kFontGeneva);
|
||||
aFontList.AppendElement(kFontAppleSymbols);
|
||||
break;
|
||||
case 0xab:
|
||||
aFontList.AppendElement(kFontKefa);
|
||||
break;
|
||||
case 0xfc:
|
||||
case 0xff:
|
||||
aFontList.AppendElement(kFontAppleSymbols);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Arial Unicode MS has lots of glyphs for obscure, use it as a last resort
|
||||
aFontList.AppendElement(kFontArialUnicodeMS);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
gfxPlatformMac::LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
|
||||
nsAString& aSystemFontName,
|
||||
gfxFontStyle& aFontStyle,
|
||||
float aDevPixPerCSSPixel)
|
||||
{
|
||||
gfxMacPlatformFontList* pfl = gfxMacPlatformFontList::PlatformFontList();
|
||||
return pfl->LookupSystemFont(aSystemFontID, aSystemFontName, aFontStyle,
|
||||
aDevPixPerCSSPixel);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
gfxPlatformMac::ReadAntiAliasingThreshold()
|
||||
{
|
||||
uint32_t threshold = 0; // default == no threshold
|
||||
|
||||
// first read prefs flag to determine whether to use the setting or not
|
||||
bool useAntiAliasingThreshold = Preferences::GetBool("gfx.use_text_smoothing_setting", false);
|
||||
|
||||
// if the pref setting is disabled, return 0 which effectively disables this feature
|
||||
if (!useAntiAliasingThreshold)
|
||||
return threshold;
|
||||
|
||||
// value set via Appearance pref panel, "Turn off text smoothing for font sizes xxx and smaller"
|
||||
CFNumberRef prefValue = (CFNumberRef)CFPreferencesCopyAppValue(CFSTR("AppleAntiAliasingThreshold"), kCFPreferencesCurrentApplication);
|
||||
|
||||
if (prefValue) {
|
||||
if (!CFNumberGetValue(prefValue, kCFNumberIntType, &threshold)) {
|
||||
threshold = 0;
|
||||
}
|
||||
CFRelease(prefValue);
|
||||
}
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
// This is the renderer output callback function, called on the vsync thread
|
||||
static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
|
||||
const CVTimeStamp* aNow,
|
||||
const CVTimeStamp* aOutputTime,
|
||||
CVOptionFlags aFlagsIn,
|
||||
CVOptionFlags* aFlagsOut,
|
||||
void* aDisplayLinkContext);
|
||||
|
||||
class OSXVsyncSource final : public VsyncSource
|
||||
{
|
||||
public:
|
||||
OSXVsyncSource()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Display& GetGlobalDisplay() override
|
||||
{
|
||||
return mGlobalDisplay;
|
||||
}
|
||||
|
||||
class OSXDisplay final : public VsyncSource::Display
|
||||
{
|
||||
public:
|
||||
OSXDisplay()
|
||||
: mDisplayLink(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
}
|
||||
|
||||
~OSXDisplay()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
static void RetryEnableVsync(nsITimer* aTimer, void* aOsxDisplay)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
OSXDisplay* osxDisplay = static_cast<OSXDisplay*>(aOsxDisplay);
|
||||
MOZ_ASSERT(osxDisplay);
|
||||
osxDisplay->EnableVsync();
|
||||
}
|
||||
|
||||
virtual void EnableVsync() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (IsVsyncEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a display link capable of being used with all active displays
|
||||
// TODO: See if we need to create an active DisplayLink for each monitor in multi-monitor
|
||||
// situations. According to the docs, it is compatible with all displays running on the computer
|
||||
// But if we have different monitors at different display rates, we may hit issues.
|
||||
if (CVDisplayLinkCreateWithActiveCGDisplays(&mDisplayLink) != kCVReturnSuccess) {
|
||||
NS_WARNING("Could not create a display link with all active displays. Retrying");
|
||||
CVDisplayLinkRelease(mDisplayLink);
|
||||
mDisplayLink = nullptr;
|
||||
|
||||
// bug 1142708 - When coming back from sleep,
|
||||
// or when changing displays, active displays may not be ready yet,
|
||||
// even if listening for the kIOMessageSystemHasPoweredOn event
|
||||
// from OS X sleep notifications.
|
||||
// Active displays are those that are drawable.
|
||||
// bug 1144638 - When changing display configurations and getting
|
||||
// notifications from CGDisplayReconfigurationCallBack, the
|
||||
// callback gets called twice for each active display
|
||||
// so it's difficult to know when all displays are active.
|
||||
// Instead, try again soon. The delay is arbitrary. 100ms chosen
|
||||
// because on a late 2013 15" retina, it takes about that
|
||||
// long to come back up from sleep.
|
||||
uint32_t delay = 100;
|
||||
mTimer->InitWithFuncCallback(RetryEnableVsync, this, delay, nsITimer::TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CVDisplayLinkSetOutputCallback(mDisplayLink, &VsyncCallback, this) != kCVReturnSuccess) {
|
||||
NS_WARNING("Could not set displaylink output callback");
|
||||
CVDisplayLinkRelease(mDisplayLink);
|
||||
mDisplayLink = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
mPreviousTimestamp = TimeStamp::Now();
|
||||
if (CVDisplayLinkStart(mDisplayLink) != kCVReturnSuccess) {
|
||||
NS_WARNING("Could not activate the display link");
|
||||
CVDisplayLinkRelease(mDisplayLink);
|
||||
mDisplayLink = nullptr;
|
||||
}
|
||||
|
||||
CVTime vsyncRate = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(mDisplayLink);
|
||||
if (vsyncRate.flags & kCVTimeIsIndefinite) {
|
||||
NS_WARNING("Could not get vsync rate, setting to 60.");
|
||||
mVsyncRate = TimeDuration::FromMilliseconds(1000.0 / 60.0);
|
||||
} else {
|
||||
int64_t timeValue = vsyncRate.timeValue;
|
||||
int64_t timeScale = vsyncRate.timeScale;
|
||||
const int milliseconds = 1000;
|
||||
float rateInMs = ((double) timeValue / (double) timeScale) * milliseconds;
|
||||
mVsyncRate = TimeDuration::FromMilliseconds(rateInMs);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void DisableVsync() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!IsVsyncEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the display link
|
||||
if (mDisplayLink) {
|
||||
CVDisplayLinkRelease(mDisplayLink);
|
||||
mDisplayLink = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsVsyncEnabled() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mDisplayLink != nullptr;
|
||||
}
|
||||
|
||||
virtual TimeDuration GetVsyncRate() override
|
||||
{
|
||||
return mVsyncRate;
|
||||
}
|
||||
|
||||
virtual void Shutdown() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
DisableVsync();
|
||||
}
|
||||
|
||||
// The vsync timestamps given by the CVDisplayLinkCallback are
|
||||
// in the future for the NEXT frame. Large parts of Gecko, such
|
||||
// as animations assume a timestamp at either now or in the past.
|
||||
// Normalize the timestamps given to the VsyncDispatchers to the vsync
|
||||
// that just occured, not the vsync that is upcoming.
|
||||
TimeStamp mPreviousTimestamp;
|
||||
|
||||
private:
|
||||
// Manages the display link render thread
|
||||
CVDisplayLinkRef mDisplayLink;
|
||||
RefPtr<nsITimer> mTimer;
|
||||
TimeDuration mVsyncRate;
|
||||
}; // OSXDisplay
|
||||
|
||||
private:
|
||||
virtual ~OSXVsyncSource()
|
||||
{
|
||||
}
|
||||
|
||||
OSXDisplay mGlobalDisplay;
|
||||
}; // OSXVsyncSource
|
||||
|
||||
static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
|
||||
const CVTimeStamp* aNow,
|
||||
const CVTimeStamp* aOutputTime,
|
||||
CVOptionFlags aFlagsIn,
|
||||
CVOptionFlags* aFlagsOut,
|
||||
void* aDisplayLinkContext)
|
||||
{
|
||||
// Executed on OS X hardware vsync thread
|
||||
OSXVsyncSource::OSXDisplay* display = (OSXVsyncSource::OSXDisplay*) aDisplayLinkContext;
|
||||
int64_t nextVsyncTimestamp = aOutputTime->hostTime;
|
||||
|
||||
mozilla::TimeStamp nextVsync = mozilla::TimeStamp::FromSystemTime(nextVsyncTimestamp);
|
||||
mozilla::TimeStamp previousVsync = display->mPreviousTimestamp;
|
||||
mozilla::TimeStamp now = TimeStamp::Now();
|
||||
|
||||
// Snow leopard sometimes sends vsync timestamps very far in the past.
|
||||
// Normalize the vsync timestamps to now.
|
||||
if (nextVsync <= previousVsync) {
|
||||
nextVsync = now;
|
||||
previousVsync = now;
|
||||
} else if (now < previousVsync) {
|
||||
// Bug 1158321 - The VsyncCallback can sometimes execute before the reported
|
||||
// vsync time. In those cases, normalize the timestamp to Now() as sending
|
||||
// timestamps in the future has undefined behavior. See the comment above
|
||||
// OSXDisplay::mPreviousTimestamp
|
||||
previousVsync = now;
|
||||
}
|
||||
|
||||
display->mPreviousTimestamp = nextVsync;
|
||||
|
||||
display->NotifyVsync(previousVsync);
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::gfx::VsyncSource>
|
||||
gfxPlatformMac::CreateHardwareVsyncSource()
|
||||
{
|
||||
RefPtr<VsyncSource> osxVsyncSource = new OSXVsyncSource();
|
||||
VsyncSource::Display& primaryDisplay = osxVsyncSource->GetGlobalDisplay();
|
||||
primaryDisplay.EnableVsync();
|
||||
if (!primaryDisplay.IsVsyncEnabled()) {
|
||||
NS_WARNING("OS X Vsync source not enabled. Falling back to software vsync.");
|
||||
return gfxPlatform::CreateHardwareVsyncSource();
|
||||
}
|
||||
|
||||
primaryDisplay.DisableVsync();
|
||||
return osxVsyncSource.forget();
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatformMac::GetPlatformCMSOutputProfile(void* &mem, size_t &size)
|
||||
{
|
||||
mem = nullptr;
|
||||
size = 0;
|
||||
|
||||
CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
|
||||
if (!cspace) {
|
||||
cspace = ::CGColorSpaceCreateDeviceRGB();
|
||||
}
|
||||
if (!cspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
CFDataRef iccp = ::CGColorSpaceCopyICCProfile(cspace);
|
||||
|
||||
::CFRelease(cspace);
|
||||
|
||||
if (!iccp) {
|
||||
return;
|
||||
}
|
||||
|
||||
// copy to external buffer
|
||||
size = static_cast<size_t>(::CFDataGetLength(iccp));
|
||||
if (size > 0) {
|
||||
void *data = malloc(size);
|
||||
if (data) {
|
||||
memcpy(data, ::CFDataGetBytePtr(iccp), size);
|
||||
mem = data;
|
||||
} else {
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
::CFRelease(iccp);
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_PLATFORM_MAC_H
|
||||
#define GFX_PLATFORM_MAC_H
|
||||
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
class VsyncSource;
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
class gfxPlatformMac : public gfxPlatform {
|
||||
public:
|
||||
gfxPlatformMac();
|
||||
virtual ~gfxPlatformMac();
|
||||
|
||||
static gfxPlatformMac *GetPlatform() {
|
||||
return (gfxPlatformMac*) gfxPlatform::GetPlatform();
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateOffscreenSurface(const IntSize& aSize,
|
||||
gfxImageFormat aFormat) override;
|
||||
|
||||
already_AddRefed<mozilla::gfx::ScaledFont>
|
||||
GetScaledFontForFont(mozilla::gfx::DrawTarget* aTarget, gfxFont *aFont) override;
|
||||
|
||||
gfxFontGroup*
|
||||
CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxTextPerfMetrics* aTextPerf,
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize) override;
|
||||
|
||||
virtual gfxPlatformFontList* CreatePlatformFontList() override;
|
||||
|
||||
bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override;
|
||||
|
||||
virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
|
||||
Script aRunScript,
|
||||
nsTArray<const char*>& aFontList) override;
|
||||
|
||||
// lookup the system font for a particular system font type and set
|
||||
// the name and style characteristics
|
||||
static void
|
||||
LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
|
||||
nsAString& aSystemFontName,
|
||||
gfxFontStyle &aFontStyle,
|
||||
float aDevPixPerCSSPixel);
|
||||
|
||||
virtual bool CanRenderContentToDataSurface() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool SupportsApzWheelInput() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RespectsFontStyleSmoothing() const override {
|
||||
// gfxMacFont respects the font smoothing hint.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RequiresAcceleratedGLContextForCompositorOGL() const override {
|
||||
// On OS X in a VM, unaccelerated CompositorOGL shows black flashes, so we
|
||||
// require accelerated GL for CompositorOGL but allow unaccelerated GL for
|
||||
// BasicCompositor.
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override;
|
||||
|
||||
// lower threshold on font anti-aliasing
|
||||
uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }
|
||||
|
||||
private:
|
||||
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) override;
|
||||
|
||||
// read in the pref value for the lower threshold on font anti-aliasing
|
||||
static uint32_t ReadAntiAliasingThreshold();
|
||||
|
||||
uint32_t mFontAntiAliasingThreshold;
|
||||
};
|
||||
|
||||
#endif /* GFX_PLATFORM_MAC_H */
|
||||
|
|
@ -427,9 +427,6 @@ private:
|
|||
|
||||
DECL_GFX_PREF(Live, "gl.ignore-dx-interop2-blacklist", IgnoreDXInterop2Blacklist, bool, false);
|
||||
DECL_GFX_PREF(Live, "gl.msaa-level", MSAALevel, uint32_t, 2);
|
||||
#if defined(XP_MACOSX)
|
||||
DECL_GFX_PREF(Live, "gl.multithreaded", GLMultithreaded, bool, false);
|
||||
#endif
|
||||
DECL_GFX_PREF(Live, "gl.require-hardware", RequireHardwareGL, bool, false);
|
||||
|
||||
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gfxQuartzNativeDrawing.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla;
|
||||
|
||||
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
|
||||
const Rect& nativeRect)
|
||||
: mDrawTarget(&aDrawTarget)
|
||||
, mNativeRect(nativeRect)
|
||||
, mCGContext(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
CGContextRef
|
||||
gfxQuartzNativeDrawing::BeginNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(!mCGContext, "BeginNativeDrawing called when drawing already in progress");
|
||||
|
||||
DrawTarget *dt = mDrawTarget;
|
||||
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
|
||||
dt->GetBackendType() != BackendType::SKIA) {
|
||||
// We need a DrawTarget that we can get a CGContextRef from:
|
||||
Matrix transform = dt->GetTransform();
|
||||
|
||||
mNativeRect = transform.TransformBounds(mNativeRect);
|
||||
mNativeRect.RoundOut();
|
||||
// Quartz theme drawing often adjusts drawing rects, so make
|
||||
// sure our surface is big enough for that.
|
||||
mNativeRect.Inflate(5);
|
||||
if (mNativeRect.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mTempDrawTarget =
|
||||
Factory::CreateDrawTarget(BackendType::SKIA,
|
||||
IntSize::Truncate(mNativeRect.width, mNativeRect.height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
|
||||
if (mTempDrawTarget) {
|
||||
transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
|
||||
mTempDrawTarget->SetTransform(transform);
|
||||
}
|
||||
dt = mTempDrawTarget;
|
||||
}
|
||||
if (dt) {
|
||||
MOZ_ASSERT(dt->GetBackendType() == BackendType::SKIA);
|
||||
mCGContext = mBorrowedContext.Init(dt);
|
||||
MOZ_ASSERT(mCGContext);
|
||||
}
|
||||
return mCGContext;
|
||||
}
|
||||
|
||||
void
|
||||
gfxQuartzNativeDrawing::EndNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
|
||||
|
||||
mBorrowedContext.Finish();
|
||||
if (mTempDrawTarget) {
|
||||
RefPtr<SourceSurface> source = mTempDrawTarget->Snapshot();
|
||||
|
||||
AutoRestoreTransform autoRestore(mDrawTarget);
|
||||
mDrawTarget->SetTransform(Matrix());
|
||||
mDrawTarget->DrawSurface(source, mNativeRect,
|
||||
Rect(0, 0, mNativeRect.width, mNativeRect.height));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _GFXQUARTZNATIVEDRAWING_H_
|
||||
#define _GFXQUARTZNATIVEDRAWING_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/BorrowedContext.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
class gfxQuartzNativeDrawing {
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::gfx::Rect Rect;
|
||||
public:
|
||||
|
||||
/* Create native Quartz drawing for a rectangle bounded by
|
||||
* nativeRect.
|
||||
*
|
||||
* Typical usage looks like:
|
||||
*
|
||||
* gfxQuartzNativeDrawing nativeDraw(ctx, nativeRect);
|
||||
* CGContextRef cgContext = nativeDraw.BeginNativeDrawing();
|
||||
* if (!cgContext)
|
||||
* return NS_ERROR_FAILURE;
|
||||
*
|
||||
* ... call Quartz operations on CGContextRef to draw to nativeRect ...
|
||||
*
|
||||
* nativeDraw.EndNativeDrawing();
|
||||
*
|
||||
* aNativeRect is the size of the surface (in Quartz/Cocoa points) that
|
||||
* will be created _if_ the gfxQuartzNativeDrawing decides to create a new
|
||||
* surface and CGContext for its drawing operations, which it then
|
||||
* composites into the target DrawTarget.
|
||||
*
|
||||
* (Note that aNativeRect will be ignored if the gfxQuartzNativeDrawing
|
||||
* uses the target DrawTarget directly.)
|
||||
*
|
||||
* The optional aBackingScale parameter is a scaling factor that will be
|
||||
* applied when creating and rendering into such a temporary surface.
|
||||
*/
|
||||
gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
|
||||
const Rect& aNativeRect);
|
||||
|
||||
/* Returns a CGContextRef which may be used for native drawing. This
|
||||
* CGContextRef is valid until EndNativeDrawing is called; if it is used
|
||||
* for drawing after that time, the result is undefined. */
|
||||
CGContextRef BeginNativeDrawing();
|
||||
|
||||
/* Marks the end of native drawing */
|
||||
void EndNativeDrawing();
|
||||
|
||||
private:
|
||||
// don't allow copying via construction or assignment
|
||||
gfxQuartzNativeDrawing(const gfxQuartzNativeDrawing&) = delete;
|
||||
const gfxQuartzNativeDrawing& operator=(const gfxQuartzNativeDrawing&) = delete;
|
||||
|
||||
// Final destination context
|
||||
RefPtr<DrawTarget> mDrawTarget;
|
||||
RefPtr<DrawTarget> mTempDrawTarget;
|
||||
mozilla::gfx::BorrowedCGContext mBorrowedContext;
|
||||
mozilla::gfx::Rect mNativeRect;
|
||||
|
||||
// saved state
|
||||
CGContextRef mCGContext;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gfxQuartzSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/HelpersCairo.h"
|
||||
|
||||
#include "cairo-quartz.h"
|
||||
|
||||
void
|
||||
gfxQuartzSurface::MakeInvalid()
|
||||
{
|
||||
mSize = mozilla::gfx::IntSize(-1, -1);
|
||||
}
|
||||
|
||||
gfxQuartzSurface::gfxQuartzSurface(const mozilla::gfx::IntSize& desiredSize,
|
||||
gfxImageFormat format)
|
||||
: mCGContext(nullptr), mSize(desiredSize)
|
||||
{
|
||||
if (!mozilla::gfx::Factory::CheckSurfaceSize(desiredSize))
|
||||
MakeInvalid();
|
||||
|
||||
unsigned int width = static_cast<unsigned int>(mSize.width);
|
||||
unsigned int height = static_cast<unsigned int>(mSize.height);
|
||||
|
||||
cairo_format_t cformat = GfxFormatToCairoFormat(format);
|
||||
cairo_surface_t *surf = cairo_quartz_surface_create(cformat, width, height);
|
||||
|
||||
mCGContext = cairo_quartz_surface_get_cg_context (surf);
|
||||
|
||||
CGContextRetain(mCGContext);
|
||||
|
||||
Init(surf);
|
||||
if (mSurfaceValid) {
|
||||
RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
|
||||
}
|
||||
}
|
||||
|
||||
gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
|
||||
const mozilla::gfx::IntSize& size)
|
||||
: mCGContext(context), mSize(size)
|
||||
{
|
||||
if (!mozilla::gfx::Factory::CheckSurfaceSize(size))
|
||||
MakeInvalid();
|
||||
|
||||
unsigned int width = static_cast<unsigned int>(mSize.width);
|
||||
unsigned int height = static_cast<unsigned int>(mSize.height);
|
||||
|
||||
cairo_surface_t *surf =
|
||||
cairo_quartz_surface_create_for_cg_context(context,
|
||||
width, height);
|
||||
|
||||
CGContextRetain(mCGContext);
|
||||
|
||||
Init(surf);
|
||||
if (mSurfaceValid) {
|
||||
RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
|
||||
}
|
||||
}
|
||||
|
||||
gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf,
|
||||
const mozilla::gfx::IntSize& aSize) :
|
||||
mSize(aSize)
|
||||
{
|
||||
mCGContext = cairo_quartz_surface_get_cg_context (csurf);
|
||||
CGContextRetain (mCGContext);
|
||||
|
||||
Init(csurf, true);
|
||||
}
|
||||
|
||||
gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
|
||||
const mozilla::gfx::IntSize& aSize,
|
||||
long stride,
|
||||
gfxImageFormat format)
|
||||
: mCGContext(nullptr), mSize(aSize.width, aSize.height)
|
||||
{
|
||||
if (!mozilla::gfx::Factory::CheckSurfaceSize(aSize))
|
||||
MakeInvalid();
|
||||
|
||||
cairo_format_t cformat = GfxFormatToCairoFormat(format);
|
||||
cairo_surface_t *surf = cairo_quartz_surface_create_for_data
|
||||
(data, cformat, aSize.width, aSize.height, stride);
|
||||
|
||||
mCGContext = cairo_quartz_surface_get_cg_context (surf);
|
||||
|
||||
CGContextRetain(mCGContext);
|
||||
|
||||
Init(surf);
|
||||
if (mSurfaceValid) {
|
||||
RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxQuartzSurface::CreateSimilarSurface(gfxContentType aType,
|
||||
const mozilla::gfx::IntSize& aSize)
|
||||
{
|
||||
cairo_surface_t *surface =
|
||||
cairo_quartz_surface_create_cg_layer(mSurface, (cairo_content_t)aType,
|
||||
aSize.width, aSize.height);
|
||||
if (cairo_surface_status(surface)) {
|
||||
cairo_surface_destroy(surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<gfxASurface> result = Wrap(surface, aSize);
|
||||
cairo_surface_destroy(surface);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<gfxImageSurface> gfxQuartzSurface::GetAsImageSurface()
|
||||
{
|
||||
cairo_surface_t *surface = cairo_quartz_surface_get_image(mSurface);
|
||||
if (!surface || cairo_surface_status(surface))
|
||||
return nullptr;
|
||||
|
||||
RefPtr<gfxASurface> img = Wrap(surface);
|
||||
|
||||
// cairo_quartz_surface_get_image returns a referenced image, and thebes
|
||||
// shares the refcounts of Cairo surfaces. However, Wrap also adds a
|
||||
// reference to the image. We need to remove one of these references
|
||||
// explicitly so we don't leak.
|
||||
img.get()->Release();
|
||||
|
||||
img->SetOpaqueRect(GetOpaqueRect());
|
||||
|
||||
return img.forget().downcast<gfxImageSurface>();
|
||||
}
|
||||
|
||||
gfxQuartzSurface::~gfxQuartzSurface()
|
||||
{
|
||||
CGContextRelease(mCGContext);
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_QUARTZSURFACE_H
|
||||
#define GFX_QUARTZSURFACE_H
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "nsSize.h"
|
||||
#include "gfxPoint.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
class gfxContext;
|
||||
class gfxImageSurface;
|
||||
|
||||
class gfxQuartzSurface : public gfxASurface {
|
||||
public:
|
||||
gfxQuartzSurface(const mozilla::gfx::IntSize&, gfxImageFormat format);
|
||||
gfxQuartzSurface(CGContextRef context, const mozilla::gfx::IntSize& size);
|
||||
gfxQuartzSurface(cairo_surface_t *csurf, const mozilla::gfx::IntSize& aSize);
|
||||
gfxQuartzSurface(unsigned char *data, const mozilla::gfx::IntSize& size, long stride, gfxImageFormat format);
|
||||
|
||||
virtual ~gfxQuartzSurface();
|
||||
|
||||
virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
|
||||
const mozilla::gfx::IntSize& aSize);
|
||||
|
||||
virtual const mozilla::gfx::IntSize GetSize() const { return mozilla::gfx::IntSize(mSize.width, mSize.height); }
|
||||
|
||||
CGContextRef GetCGContext() { return mCGContext; }
|
||||
|
||||
already_AddRefed<gfxImageSurface> GetAsImageSurface();
|
||||
|
||||
protected:
|
||||
void MakeInvalid();
|
||||
|
||||
CGContextRef mCGContext;
|
||||
mozilla::gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
#endif /* GFX_QUARTZSURFACE_H */
|
||||
|
|
@ -518,11 +518,6 @@ HasSyntheticBoldOrColor(const gfxTextRun *aRun, gfxTextRun::Range aRange)
|
|||
if (fe->TryGetSVGData(font) || fe->TryGetColorGlyphs()) {
|
||||
return true;
|
||||
}
|
||||
#if defined(XP_MACOSX) // sbix fonts only supported via Core Text
|
||||
if (fe->HasFontTable(TRUETYPE_TAG('s', 'b', 'i', 'x'))) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -57,24 +57,7 @@ EXPORTS.mozilla.gfx += [
|
|||
'PrintTargetThebes.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
EXPORTS += [
|
||||
'gfxPlatformMac.h',
|
||||
'gfxQuartzNativeDrawing.h',
|
||||
'gfxQuartzSurface.h',
|
||||
]
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'PrintTargetCG.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'gfxCoreTextShaper.cpp',
|
||||
'gfxMacFont.cpp',
|
||||
'gfxPlatformMac.cpp',
|
||||
'gfxQuartzNativeDrawing.cpp',
|
||||
'gfxQuartzSurface.cpp',
|
||||
'PrintTargetCG.cpp',
|
||||
]
|
||||
elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
EXPORTS += [
|
||||
'gfxFontconfigFonts.h',
|
||||
'gfxFT2FontBase.h',
|
||||
|
|
@ -185,11 +168,7 @@ SOURCES += [
|
|||
'VsyncSource.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'gfxMacPlatformFontList.mm',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
SOURCES += [
|
||||
'D3D11Checks.cpp',
|
||||
'DeviceManagerDx.cpp',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
// Copyright (c) 2021 Moonchild Productions.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
|
@ -319,9 +320,7 @@ void FastConvertYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"2:"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
void FastConvertYUVToRGB32Row(const uint8* y_buf,
|
||||
|
|
@ -412,9 +411,7 @@ void ScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"2:"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
void ScaleYUVToRGB32Row(const uint8* y_buf,
|
||||
|
|
@ -544,9 +541,7 @@ void LinearScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"movd %mm1, (%ebp)\n"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
void LinearScaleYUVToRGB32Row(const uint8* y_buf,
|
||||
|
|
@ -577,11 +572,7 @@ void PICConvertYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
|
||||
asm(
|
||||
".text\n"
|
||||
#if defined(XP_MACOSX)
|
||||
"_PICConvertYUVToRGB32Row_SSE:\n"
|
||||
#else
|
||||
"PICConvertYUVToRGB32Row_SSE:\n"
|
||||
#endif
|
||||
"PICConvertYUVToRGB32Row_SSE:\n"
|
||||
"pusha\n"
|
||||
"mov 0x24(%esp),%edx\n"
|
||||
"mov 0x28(%esp),%edi\n"
|
||||
|
|
@ -630,9 +621,7 @@ void PICConvertYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"2:"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
void FastConvertYUVToRGB32Row(const uint8* y_buf,
|
||||
|
|
@ -660,11 +649,7 @@ void PICScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
|
||||
asm(
|
||||
".text\n"
|
||||
#if defined(XP_MACOSX)
|
||||
"_PICScaleYUVToRGB32Row_SSE:\n"
|
||||
#else
|
||||
"PICScaleYUVToRGB32Row_SSE:\n"
|
||||
#endif
|
||||
"PICScaleYUVToRGB32Row_SSE:\n"
|
||||
"pusha\n"
|
||||
"mov 0x24(%esp),%edx\n"
|
||||
"mov 0x28(%esp),%edi\n"
|
||||
|
|
@ -727,9 +712,7 @@ void PICScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"2:"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
void ScaleYUVToRGB32Row(const uint8* y_buf,
|
||||
|
|
@ -758,11 +741,7 @@ void PICLinearScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
|
||||
asm(
|
||||
".text\n"
|
||||
#if defined(XP_MACOSX)
|
||||
"_PICLinearScaleYUVToRGB32Row_SSE:\n"
|
||||
#else
|
||||
"PICLinearScaleYUVToRGB32Row_SSE:\n"
|
||||
#endif
|
||||
"PICLinearScaleYUVToRGB32Row_SSE:\n"
|
||||
"pusha\n"
|
||||
"mov 0x24(%esp),%edx\n"
|
||||
"mov 0x30(%esp),%ebp\n"
|
||||
|
|
@ -865,9 +844,7 @@ void PICLinearScaleYUVToRGB32Row_SSE(const uint8* y_buf,
|
|||
"movd %mm1, (%ebp)\n"
|
||||
"popa\n"
|
||||
"ret\n"
|
||||
#if !defined(XP_MACOSX)
|
||||
".previous\n"
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue