/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=2 expandtab: */ /* 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"nsDeviceContext.h" #include <algorithm> // for max #include"gfxContext.h" #include"gfxPoint.h"// for gfxSize #include"gfxTextRun.h"// for gfxFontGroup #include"mozilla/LookAndFeel.h" #include"mozilla/gfx/PathHelpers.h" #include"mozilla/gfx/PrintTarget.h" #include"mozilla/ProfilerMarkers.h" #include"mozilla/StaticPrefs_layout.h" #include"mozilla/Try.h"// for MOZ_TRY #include"mozilla/widget/Screen.h"// for Screen #include"nsDebug.h"// for NS_ASSERTION, etc #include"nsFontMetrics.h"// for nsFontMetrics #include"nsIDeviceContextSpec.h"// for nsIDeviceContextSpec #include"nsIWidget.h"// for nsIWidget, NS_NATIVE_WINDOW #include"nsRect.h"// for nsRect #include"nsTArray.h"// for nsTArray, nsTArray_Impl #include"mozilla/gfx/Logging.h" #include"mozilla/widget/ScreenManager.h"// for ScreenManager
usingnamespace mozilla; usingnamespace mozilla::gfx; using mozilla::widget::ScreenManager;
nsDeviceContext::nsDeviceContext()
: mWidth(0),
mHeight(0),
mAppUnitsPerDevPixel(-1),
mAppUnitsPerDevPixelAtUnitFullZoom(-1),
mAppUnitsPerPhysicalInch(-1),
mFullZoom(1.0f),
mPrintingScale(1.0f),
mPrintingTranslate(gfxPoint(0, 0)),
mIsCurrentlyPrintingDoc(false) {
MOZ_ASSERT(NS_IsMainThread(), "nsDeviceContext created off main thread");
}
nsDeviceContext::~nsDeviceContext() = default;
void nsDeviceContext::SetDPI() { float dpi;
// Use the printing DC to determine DPI values, if we have one. if (mDeviceContextSpec) {
dpi = mDeviceContextSpec->GetDPI();
mPrintingScale = mDeviceContextSpec->GetPrintingScale();
mPrintingTranslate = mDeviceContextSpec->GetPrintingTranslate();
mAppUnitsPerDevPixelAtUnitFullZoom =
NS_lround((AppUnitsPerCSSPixel() * 96) / dpi);
} else { // A value of -1 means use the maximum of 96 and the system DPI. // A value of 0 means use the system DPI. A positive value is used as the // DPI. This sets the physical size of a device pixel and thus controls the // interpretation of physical units.
int32_t prefDPI = StaticPrefs::layout_css_dpi(); if (prefDPI > 0) {
dpi = prefDPI;
} elseif (mWidget) {
dpi = mWidget->GetDPI();
MOZ_ASSERT(dpi > 0); if (prefDPI < 0) {
dpi = std::max(96.0f, dpi);
}
} else {
dpi = 96.0f;
}
// We can't assert |!mIsInitialized| here since EndSwapDocShellsForDocument // re-initializes nsDeviceContext objects. We can only assert in // InitForPrinting (below).
mIsInitialized = true;
mWidget = aWidget;
SetDPI();
}
// XXX This is only for printing. We should make that obvious in the name.
UniquePtr<gfxContext> nsDeviceContext::CreateRenderingContext() { return CreateRenderingContextCommon(/* not a reference context */ false);
}
if (NS_WARN_IF(!mPrintTarget)) { // Printing canceled already. return nullptr;
}
RefPtr<gfx::DrawTarget> dt; if (aWantReferenceContext) {
dt = mPrintTarget->GetReferenceDrawTarget();
} else { // This will be null if printing a page from the parent process.
RefPtr<DrawEventRecorder> recorder;
mDeviceContextSpec->GetDrawEventRecorder(getter_AddRefs(recorder));
dt = mPrintTarget->MakeDrawTarget(gfx::IntSize(mWidth, mHeight), recorder);
}
if (!dt || !dt->IsValid()) {
gfxCriticalNote << "Failed to create draw target in device context sized "
<< mWidth << "x" << mHeight << " and pointer "
<< hexa(mPrintTarget); return nullptr;
}
if (NS_SUCCEEDED(rv)) { if (mDeviceContextSpec) {
rv = mDeviceContextSpec->BeginDocument(aTitle, aPrintToFileName,
aStartPage, aEndPage);
}
mIsCurrentlyPrintingDoc = true;
}
// Warn about any failure (except user cancelling):
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv) || rv == NS_ERROR_ABORT, "nsDeviceContext::BeginDocument failed");
if (mPrintTarget) { auto result = mPrintTarget->EndPrinting(); if (NS_FAILED(result)) { return PrintEndDocumentPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
__func__);
}
mPrintTarget->Finish();
mPrintTarget = nullptr;
}
if (mDeviceContextSpec) { return mDeviceContextSpec->EndDocument();
}
if (mDeviceContextSpec) {
MOZ_TRY(mDeviceContextSpec->BeginPage(aSizeInPoints));
} if (mPrintTarget) {
MOZ_TRY(mPrintTarget->BeginPage(aSizeInPoints));
} return NS_OK;
}
nsresult nsDeviceContext::EndPage() {
MOZ_DIAGNOSTIC_ASSERT(!mIsCurrentlyPrintingDoc || mPrintTarget, "What nulled out our print target while printing?");
AUTO_PROFILER_MARKER_TEXT("DeviceContext Printing", LAYOUT_Printing, {}, "nsDeviceContext::EndPage"_ns);
if (mPrintTarget) {
MOZ_TRY(mPrintTarget->EndPage());
} if (mDeviceContextSpec) {
MOZ_TRY(mDeviceContextSpec->EndPage());
} return NS_OK;
}
already_AddRefed<widget::Screen> nsDeviceContext::FindScreen() { if (mWidget) {
CheckDPIChange(); if (RefPtr<widget::Screen> screen = mWidget->GetWidgetScreen()) { return screen.forget();
}
} return ScreenManager::GetSingleton().GetPrimaryScreen();
}
bool nsDeviceContext::CalcPrintingSize() {
gfxSize size(mPrintTarget->GetSize()); // For printing, CSS inches and physical inches are identical // so it doesn't matter which we use here
mWidth = NSToCoordRound(size.width * AppUnitsPerPhysicalInch() /
POINTS_PER_INCH_FLOAT);
mHeight = NSToCoordRound(size.height * AppUnitsPerPhysicalInch() /
POINTS_PER_INCH_FLOAT);
int32_t nsDeviceContext::AppUnitsPerDevPixelInTopLevelChromePage() const { // The only zoom that applies to chrome pages is the system zoom, if any. return ApplyFullZoom(mAppUnitsPerDevPixelAtUnitFullZoom,
LookAndFeel::SystemZoomSettings().mFullZoom);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.