зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central a=merge
This commit is contained in:
Коммит
c7772ecfed
|
@ -2937,6 +2937,7 @@ dependencies = [
|
|||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plane-split 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -9,10 +9,6 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%
|
|||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 28800); // 8 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=192 hours
|
||||
pref("app.update.promptWaitTime", 691200);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
|
|
@ -7,10 +7,6 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/projects/firefox/%
|
|||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 7200); // 2 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=12 hours
|
||||
pref("app.update.promptWaitTime", 43200);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
|
|
@ -7,10 +7,6 @@ pref("startup.homepage_welcome_url", "about:welcome");
|
|||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// Interval: Time between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 43200); // 12 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=192 hours
|
||||
pref("app.update.promptWaitTime", 691200);
|
||||
// app.update.url.manual: URL user can browse to manually if for some reason
|
||||
|
|
|
@ -7,9 +7,6 @@ pref("startup.homepage_welcome_url", "");
|
|||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 86400); // 24 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
pref("app.update.download.backgroundInterval", 60);
|
||||
// Give the user x seconds to react before showing the big UI. default=24 hours
|
||||
pref("app.update.promptWaitTime", 86400);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
|
|
@ -123,12 +123,12 @@ function getPostUpdateOverridePage(defaultOverridePage) {
|
|||
// history.
|
||||
if (um.activeUpdate) {
|
||||
var update = um.activeUpdate
|
||||
.QueryInterface(Ci.nsIPropertyBag);
|
||||
.QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
} else {
|
||||
// If the updates.xml file is deleted then getUpdateAt will throw.
|
||||
try {
|
||||
update = um.getUpdateAt(0)
|
||||
.QueryInterface(Ci.nsIPropertyBag);
|
||||
.QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
} catch (e) {
|
||||
Cu.reportError("Unable to find update: " + e);
|
||||
return defaultOverridePage;
|
||||
|
|
|
@ -1865,7 +1865,7 @@ BrowserGlue.prototype = {
|
|||
getService(Ci.nsIUpdateManager);
|
||||
try {
|
||||
// If the updates.xml file is deleted then getUpdateAt will throw.
|
||||
var update = um.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
|
||||
var update = um.getUpdateAt(0).QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
} catch (e) {
|
||||
// This should never happen.
|
||||
Cu.reportError("Unable to find update: " + e);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* 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 "SVGElement.h"
|
||||
#include "DOMSVGPathSegList.h"
|
||||
#include "DOMSVGPathSeg.h"
|
||||
#include "nsError.h"
|
||||
|
@ -12,8 +11,11 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "SVGPathSegUtils.h"
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "mozilla/dom/SVGPathSegListBinding.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// See the comment in this file's header.
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* 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 "SVGElement.h"
|
||||
#include "DOMSVGPointList.h"
|
||||
#include "DOMSVGPoint.h"
|
||||
#include "nsError.h"
|
||||
|
@ -12,9 +11,12 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "mozilla/dom/SVGPointListBinding.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// See the comment in this file's header.
|
||||
|
||||
// local helper functions
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include "SVGAnimatedNumberList.h"
|
||||
|
||||
#include "DOMSVGAnimatedNumberList.h"
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "SVGElement.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "SVGNumberListSMILType.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nsresult SVGAnimatedNumberList::SetBaseValueString(const nsAString &aValue) {
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "nsSMILValue.h"
|
||||
#include "SVGPathSegListSMILType.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// See the comments in this file's header!
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include "SVGAnimatedPointList.h"
|
||||
|
||||
#include "DOMSVGPointList.h"
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "SVGElement.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "SVGPointListSMILType.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// See the comments in this file's header!
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -34,10 +34,95 @@
|
|||
#include "SVGPathData.h"
|
||||
#include "SVGPathElement.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::SVGPreserveAspectRatio_Binding;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
static bool ParseNumber(RangedPtr<const char16_t>& aIter,
|
||||
const RangedPtr<const char16_t>& aEnd, double& aValue) {
|
||||
int32_t sign;
|
||||
if (!SVGContentUtils::ParseOptionalSign(aIter, aEnd, sign)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Absolute value of the integer part of the mantissa.
|
||||
double intPart = 0.0;
|
||||
|
||||
bool gotDot = *aIter == '.';
|
||||
|
||||
if (!gotDot) {
|
||||
if (!mozilla::IsAsciiDigit(*aIter)) {
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
intPart = 10.0 * intPart + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
|
||||
if (aIter != aEnd) {
|
||||
gotDot = *aIter == '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Fractional part of the mantissa.
|
||||
double fracPart = 0.0;
|
||||
|
||||
if (gotDot) {
|
||||
++aIter;
|
||||
if (aIter == aEnd || !mozilla::IsAsciiDigit(*aIter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Power of ten by which we need to divide the fraction
|
||||
double divisor = 1.0;
|
||||
|
||||
do {
|
||||
fracPart = 10.0 * fracPart + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
divisor *= 10.0;
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
|
||||
fracPart /= divisor;
|
||||
}
|
||||
|
||||
bool gotE = false;
|
||||
int32_t exponent = 0;
|
||||
int32_t expSign;
|
||||
|
||||
if (aIter != aEnd && (*aIter == 'e' || *aIter == 'E')) {
|
||||
RangedPtr<const char16_t> expIter(aIter);
|
||||
|
||||
++expIter;
|
||||
if (expIter != aEnd) {
|
||||
expSign = *expIter == '-' ? -1 : 1;
|
||||
if (*expIter == '-' || *expIter == '+') {
|
||||
++expIter;
|
||||
}
|
||||
if (expIter != aEnd && mozilla::IsAsciiDigit(*expIter)) {
|
||||
// At this point we're sure this is an exponent
|
||||
// and not the start of a unit such as em or ex.
|
||||
gotE = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotE) {
|
||||
aIter = expIter;
|
||||
do {
|
||||
exponent = 10.0 * exponent + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble the number
|
||||
aValue = sign * (intPart + fracPart);
|
||||
if (gotE) {
|
||||
aValue *= pow(10.0, expSign * exponent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
SVGSVGElement* SVGContentUtils::GetOuterSVGElement(SVGElement* aSVGElement) {
|
||||
|
@ -589,90 +674,6 @@ gfx::Matrix SVGContentUtils::GetViewBoxTransform(
|
|||
return gfx::Matrix(a, 0.0f, 0.0f, d, e, f);
|
||||
}
|
||||
|
||||
static bool ParseNumber(RangedPtr<const char16_t>& aIter,
|
||||
const RangedPtr<const char16_t>& aEnd, double& aValue) {
|
||||
int32_t sign;
|
||||
if (!SVGContentUtils::ParseOptionalSign(aIter, aEnd, sign)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Absolute value of the integer part of the mantissa.
|
||||
double intPart = 0.0;
|
||||
|
||||
bool gotDot = *aIter == '.';
|
||||
|
||||
if (!gotDot) {
|
||||
if (!mozilla::IsAsciiDigit(*aIter)) {
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
intPart = 10.0 * intPart + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
|
||||
if (aIter != aEnd) {
|
||||
gotDot = *aIter == '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Fractional part of the mantissa.
|
||||
double fracPart = 0.0;
|
||||
|
||||
if (gotDot) {
|
||||
++aIter;
|
||||
if (aIter == aEnd || !mozilla::IsAsciiDigit(*aIter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Power of ten by which we need to divide the fraction
|
||||
double divisor = 1.0;
|
||||
|
||||
do {
|
||||
fracPart = 10.0 * fracPart + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
divisor *= 10.0;
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
|
||||
fracPart /= divisor;
|
||||
}
|
||||
|
||||
bool gotE = false;
|
||||
int32_t exponent = 0;
|
||||
int32_t expSign;
|
||||
|
||||
if (aIter != aEnd && (*aIter == 'e' || *aIter == 'E')) {
|
||||
RangedPtr<const char16_t> expIter(aIter);
|
||||
|
||||
++expIter;
|
||||
if (expIter != aEnd) {
|
||||
expSign = *expIter == '-' ? -1 : 1;
|
||||
if (*expIter == '-' || *expIter == '+') {
|
||||
++expIter;
|
||||
}
|
||||
if (expIter != aEnd && mozilla::IsAsciiDigit(*expIter)) {
|
||||
// At this point we're sure this is an exponent
|
||||
// and not the start of a unit such as em or ex.
|
||||
gotE = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotE) {
|
||||
aIter = expIter;
|
||||
do {
|
||||
exponent = 10.0 * exponent + mozilla::AsciiAlphanumericToNumber(*aIter);
|
||||
++aIter;
|
||||
} while (aIter != aEnd && mozilla::IsAsciiDigit(*aIter));
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble the number
|
||||
aValue = sign * (intPart + fracPart);
|
||||
if (gotE) {
|
||||
aValue *= pow(10.0, expSign * exponent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class floatType>
|
||||
bool SVGContentUtils::ParseNumber(RangedPtr<const char16_t>& aIter,
|
||||
const RangedPtr<const char16_t>& aEnd,
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#ifndef __NS_SVGDATAPARSER_H__
|
||||
#define __NS_SVGDATAPARSER_H__
|
||||
|
||||
#include <cctype>
|
||||
#include "mozilla/RangedPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -7,7 +7,13 @@
|
|||
#ifndef mozilla_dom_SVGElementFactory_h
|
||||
#define mozilla_dom_SVGElementFactory_h
|
||||
|
||||
#include "nsError.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/dom/FromParser.h"
|
||||
#include "mozilla/dom/NodeInfo.h"
|
||||
|
||||
class nsAtom;
|
||||
class nsIContent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
|
@ -4,19 +4,20 @@
|
|||
* 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 "SVGLength.h"
|
||||
#include "SVGElement.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/SVGElement.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::SVGLength_Binding;
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
// Declare some helpers defined below:
|
||||
static void GetUnitString(nsAString& unit, uint16_t unitType);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "SVGAnimatedPreserveAspectRatio.h"
|
||||
#include "nsError.h"
|
||||
#include "mozilla/dom/SVGAngle.h"
|
||||
#include "mozilla/dom/SVGGeometryElement.h"
|
||||
#include "mozilla/dom/SVGLengthBinding.h"
|
||||
#include "mozilla/dom/SVGMarkerElement.h"
|
||||
#include "mozilla/dom/SVGMarkerElementBinding.h"
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "SVGPathSegUtils.h"
|
||||
#include "SVGPathData.h"
|
||||
|
||||
using namespace mozilla::dom::SVGPathSeg_Binding;
|
||||
|
||||
// Indices of boolean flags within 'arc' segment chunks in path-data arrays
|
||||
// (where '0' would correspond to the index of the encoded segment type):
|
||||
#define LARGE_ARC_FLAG_IDX 4
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsTextFormatter.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom::SVGPathSeg_Binding;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/dom/SVGSVGElementBinding.h"
|
||||
#include "mozilla/dom/SVGMatrix.h"
|
||||
#include "mozilla/dom/SVGRect.h"
|
||||
#include "mozilla/dom/SVGViewElement.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "SVGStringList.h"
|
||||
#include "nsError.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "SVGContentUtils.h"
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "mozilla/dom/SVGTests.h"
|
||||
#include "DOMSVGStringList.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsSVGFeatures.h"
|
||||
#include "mozilla/dom/SVGSwitchElement.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
|
|
|
@ -1 +1 @@
|
|||
6bdd0d26afe3fc5a24f10c19d4ca8569d0182a37
|
||||
8476ed5e134e54f2facb01ea45e8a2008c8ba8da
|
||||
|
|
|
@ -1547,6 +1547,7 @@ dependencies = [
|
|||
"gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozangle 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -72,6 +72,7 @@ rand = "0.4"
|
|||
|
||||
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||
freetype = { version = "0.4", default-features = false }
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
dwrote = "0.6.3"
|
||||
|
|
|
@ -18,7 +18,7 @@ use image::{self, Repetition};
|
|||
use intern;
|
||||
use internal_types::FastHashSet;
|
||||
use prim_store::{ClipData, ImageMaskData, SpaceMapper, VisibleMaskImageTile};
|
||||
use prim_store::{PointKey, SizeKey, RectangleKey};
|
||||
use prim_store::{PointKey, PrimitiveInstance, SizeKey, RectangleKey};
|
||||
use render_task::to_cache_size;
|
||||
use resource_cache::{ImageRequest, ResourceCache};
|
||||
use std::{cmp, u32};
|
||||
|
@ -198,7 +198,7 @@ impl ClipChainId {
|
|||
|
||||
// A clip chain node is an id for a range of clip sources,
|
||||
// and a link to a parent clip chain node, or ClipChainId::NONE.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ClipChainNode {
|
||||
pub handle: ClipDataHandle,
|
||||
pub local_pos: LayoutPoint,
|
||||
|
@ -516,7 +516,7 @@ impl ClipStore {
|
|||
// information, and a clip chain id, build an optimized clip chain instance.
|
||||
pub fn build_clip_chain_instance(
|
||||
&mut self,
|
||||
clip_chain_id: ClipChainId,
|
||||
prim_instance: &PrimitiveInstance,
|
||||
local_prim_rect: LayoutRect,
|
||||
local_prim_clip_rect: LayoutRect,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
|
@ -536,7 +536,7 @@ impl ClipStore {
|
|||
// smallest possible local/device clip area.
|
||||
|
||||
self.clip_node_info.clear();
|
||||
let mut current_clip_chain_id = clip_chain_id;
|
||||
let mut current_clip_chain_id = prim_instance.clip_chain_id;
|
||||
|
||||
// for each clip chain node
|
||||
while current_clip_chain_id != ClipChainId::NONE {
|
||||
|
@ -551,10 +551,12 @@ impl ClipStore {
|
|||
collector.insert(current_clip_chain_id);
|
||||
}
|
||||
None => {
|
||||
if prim_instance.is_chased() {
|
||||
println!("\t\tclip node (from chain) {:?} at {:?}",
|
||||
clip_chain_node.spatial_node_index, clip_chain_node.local_pos);
|
||||
}
|
||||
if !add_clip_node_to_current_chain(
|
||||
clip_chain_node.handle,
|
||||
clip_chain_node.spatial_node_index,
|
||||
clip_chain_node.local_pos,
|
||||
clip_chain_node,
|
||||
spatial_node_index,
|
||||
&mut local_clip_rect,
|
||||
&mut self.clip_node_info,
|
||||
|
@ -573,15 +575,14 @@ impl ClipStore {
|
|||
// handled as part of this rasterization root.
|
||||
if let Some(clip_node_collector) = clip_node_collector {
|
||||
for clip_chain_id in &clip_node_collector.clips {
|
||||
let (handle, clip_spatial_node_index, local_pos) = {
|
||||
let clip_chain_node = &self.clip_chain_nodes[clip_chain_id.0 as usize];
|
||||
(clip_chain_node.handle, clip_chain_node.spatial_node_index, clip_chain_node.local_pos)
|
||||
};
|
||||
let clip_chain_node = &self.clip_chain_nodes[clip_chain_id.0 as usize];
|
||||
if prim_instance.is_chased() {
|
||||
println!("\t\tclip node (from collector) {:?} at {:?}",
|
||||
clip_chain_node.spatial_node_index, clip_chain_node.local_pos);
|
||||
}
|
||||
|
||||
if !add_clip_node_to_current_chain(
|
||||
handle,
|
||||
clip_spatial_node_index,
|
||||
local_pos,
|
||||
clip_chain_node,
|
||||
spatial_node_index,
|
||||
&mut local_clip_rect,
|
||||
&mut self.clip_node_info,
|
||||
|
@ -655,6 +656,10 @@ impl ClipStore {
|
|||
resource_cache,
|
||||
);
|
||||
|
||||
if prim_instance.is_chased() {
|
||||
println!("\t\tpartial {:?}", node.item);
|
||||
}
|
||||
|
||||
// As a special case, a partial accept of a clip rect that is
|
||||
// in the same coordinate system as the primitive doesn't need
|
||||
// a clip mask. Instead, it can be handled by the primitive
|
||||
|
@ -1362,77 +1367,73 @@ impl ClipNodeCollector {
|
|||
// for the current clip chain. Returns false if the clip
|
||||
// results in the entire primitive being culled out.
|
||||
fn add_clip_node_to_current_chain(
|
||||
handle: ClipDataHandle,
|
||||
clip_spatial_node_index: SpatialNodeIndex,
|
||||
local_pos: LayoutPoint,
|
||||
node: &ClipChainNode,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
local_clip_rect: &mut LayoutRect,
|
||||
clip_node_info: &mut Vec<ClipNodeInfo>,
|
||||
clip_data_store: &ClipDataStore,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) -> bool {
|
||||
let clip_node = &clip_data_store[handle];
|
||||
let clip_spatial_node = &clip_scroll_tree.spatial_nodes[clip_spatial_node_index.0];
|
||||
let clip_node = &clip_data_store[node.handle];
|
||||
let clip_spatial_node = &clip_scroll_tree.spatial_nodes[node.spatial_node_index.0];
|
||||
let ref_spatial_node = &clip_scroll_tree.spatial_nodes[spatial_node_index.0];
|
||||
|
||||
// Determine the most efficient way to convert between coordinate
|
||||
// systems of the primitive and clip node.
|
||||
let conversion = if spatial_node_index == clip_spatial_node_index {
|
||||
Some(ClipSpaceConversion::Local)
|
||||
let conversion = if spatial_node_index == node.spatial_node_index {
|
||||
ClipSpaceConversion::Local
|
||||
} else if ref_spatial_node.coordinate_system_id == clip_spatial_node.coordinate_system_id {
|
||||
let scale_offset = ref_spatial_node.coordinate_system_relative_scale_offset
|
||||
.inverse()
|
||||
.accumulate(&clip_spatial_node.coordinate_system_relative_scale_offset);
|
||||
Some(ClipSpaceConversion::ScaleOffset(scale_offset))
|
||||
ClipSpaceConversion::ScaleOffset(scale_offset)
|
||||
} else {
|
||||
let xf = clip_scroll_tree.get_relative_transform(
|
||||
clip_spatial_node_index,
|
||||
match clip_scroll_tree.get_relative_transform(
|
||||
node.spatial_node_index,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
);
|
||||
|
||||
xf.map(|xf| {
|
||||
ClipSpaceConversion::Transform(xf.with_destination::<WorldPixel>())
|
||||
})
|
||||
) {
|
||||
None => return true,
|
||||
Some(xf) => ClipSpaceConversion::Transform(xf.with_destination::<WorldPixel>()),
|
||||
}
|
||||
};
|
||||
|
||||
// If we can convert spaces, try to reduce the size of the region
|
||||
// requested, and cache the conversion information for the next step.
|
||||
if let Some(conversion) = conversion {
|
||||
if let Some(clip_rect) = clip_node.item.get_local_clip_rect(local_pos) {
|
||||
match conversion {
|
||||
ClipSpaceConversion::Local => {
|
||||
*local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
|
||||
Some(rect) => rect,
|
||||
None => return false,
|
||||
};
|
||||
}
|
||||
ClipSpaceConversion::ScaleOffset(ref scale_offset) => {
|
||||
let clip_rect = scale_offset.map_rect(&clip_rect);
|
||||
*local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
|
||||
Some(rect) => rect,
|
||||
None => return false,
|
||||
};
|
||||
}
|
||||
ClipSpaceConversion::Transform(..) => {
|
||||
// TODO(gw): In the future, we can reduce the size
|
||||
// of the pic_clip_rect here. To do this,
|
||||
// we can use project_rect or the
|
||||
// inverse_rect_footprint method, depending
|
||||
// on the relationship of the clip, pic
|
||||
// and primitive spatial nodes.
|
||||
// I have left this for now until we
|
||||
// find some good test cases where this
|
||||
// would be a worthwhile perf win.
|
||||
}
|
||||
if let Some(clip_rect) = clip_node.item.get_local_clip_rect(node.local_pos) {
|
||||
match conversion {
|
||||
ClipSpaceConversion::Local => {
|
||||
*local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
|
||||
Some(rect) => rect,
|
||||
None => return false,
|
||||
};
|
||||
}
|
||||
ClipSpaceConversion::ScaleOffset(ref scale_offset) => {
|
||||
let clip_rect = scale_offset.map_rect(&clip_rect);
|
||||
*local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
|
||||
Some(rect) => rect,
|
||||
None => return false,
|
||||
};
|
||||
}
|
||||
ClipSpaceConversion::Transform(..) => {
|
||||
// TODO(gw): In the future, we can reduce the size
|
||||
// of the pic_clip_rect here. To do this,
|
||||
// we can use project_rect or the
|
||||
// inverse_rect_footprint method, depending
|
||||
// on the relationship of the clip, pic
|
||||
// and primitive spatial nodes.
|
||||
// I have left this for now until we
|
||||
// find some good test cases where this
|
||||
// would be a worthwhile perf win.
|
||||
}
|
||||
}
|
||||
clip_node_info.push(ClipNodeInfo {
|
||||
conversion,
|
||||
local_pos,
|
||||
handle,
|
||||
spatial_node_index: clip_spatial_node_index,
|
||||
})
|
||||
}
|
||||
|
||||
clip_node_info.push(ClipNodeInfo {
|
||||
conversion,
|
||||
local_pos: node.local_pos,
|
||||
handle: node.handle,
|
||||
spatial_node_index: node.spatial_node_index,
|
||||
});
|
||||
|
||||
true
|
||||
}
|
||||
|
|
|
@ -153,6 +153,8 @@ extern crate core_text;
|
|||
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
extern crate freetype;
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
extern crate libc;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
extern crate dwrote;
|
||||
|
|
|
@ -339,10 +339,7 @@ impl FontContext {
|
|||
match self.ct_fonts.entry((font_key, size, variations.to_vec())) {
|
||||
Entry::Occupied(entry) => Some((*entry.get()).clone()),
|
||||
Entry::Vacant(entry) => {
|
||||
let cg_font = match self.cg_fonts.get(&font_key) {
|
||||
None => return None,
|
||||
Some(cg_font) => cg_font,
|
||||
};
|
||||
let cg_font = self.cg_fonts.get(&font_key)?;
|
||||
let ct_font = new_ct_font_with_variations(cg_font, size.to_f64_px(), variations);
|
||||
entry.insert(ct_font.clone());
|
||||
Some(ct_font)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use api::{ColorU, GlyphDimensions, FontKey, FontRenderMode};
|
||||
use api::{FontInstancePlatformOptions, FontLCDFilter, FontHinting};
|
||||
use api::{FontInstanceFlags, NativeFontHandle};
|
||||
use api::{FontInstanceFlags, FontVariation, NativeFontHandle};
|
||||
use freetype::freetype::{FT_BBox, FT_Outline_Translate, FT_Pixel_Mode, FT_Render_Mode};
|
||||
use freetype::freetype::{FT_Done_Face, FT_Error, FT_Get_Char_Index, FT_Int32};
|
||||
use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos};
|
||||
|
@ -12,20 +12,26 @@ use freetype::freetype::{FT_F26Dot6, FT_Face, FT_Glyph_Format, FT_Long, FT_UInt}
|
|||
use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Face, FT_New_Memory_Face};
|
||||
use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph};
|
||||
use freetype::freetype::{FT_Library, FT_Outline_Get_CBox, FT_Set_Char_Size, FT_Select_Size};
|
||||
use freetype::freetype::{FT_Fixed, FT_Matrix, FT_Set_Transform};
|
||||
use freetype::freetype::{FT_Fixed, FT_Matrix, FT_Set_Transform, FT_String, FT_ULong};
|
||||
use freetype::freetype::{FT_Err_Unimplemented_Feature};
|
||||
use freetype::freetype::{FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_FORCE_AUTOHINT};
|
||||
use freetype::freetype::{FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH, FT_LOAD_NO_AUTOHINT};
|
||||
use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING, FT_LOAD_VERTICAL_LAYOUT};
|
||||
use freetype::freetype::{FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES};
|
||||
use freetype::freetype::{FT_FACE_FLAG_MULTIPLE_MASTERS};
|
||||
use freetype::succeeded;
|
||||
use glyph_rasterizer::{FontInstance, GlyphFormat, GlyphKey, GlyphRasterResult, RasterizedGlyph};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use glyph_rasterizer::NativeFontHandleWrapper;
|
||||
use internal_types::{FastHashMap, ResourceCacheError};
|
||||
#[cfg(not(target_os = "android"))]
|
||||
use libc::{dlsym, RTLD_DEFAULT};
|
||||
use libc::free;
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use pathfinder_font_renderer::freetype as pf_freetype;
|
||||
use std::{cmp, mem, ptr, slice};
|
||||
use std::cmp::max;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::ffi::CString;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -38,16 +44,141 @@ const FT_LOAD_TARGET_MONO: FT_UInt = 2 << 16;
|
|||
const FT_LOAD_TARGET_LCD: FT_UInt = 3 << 16;
|
||||
const FT_LOAD_TARGET_LCD_V: FT_UInt = 4 << 16;
|
||||
|
||||
struct Face {
|
||||
face: FT_Face,
|
||||
#[repr(C)]
|
||||
struct FT_Var_Axis {
|
||||
pub name: *mut FT_String,
|
||||
pub minimum: FT_Fixed,
|
||||
pub def: FT_Fixed,
|
||||
pub maximum: FT_Fixed,
|
||||
pub tag: FT_ULong,
|
||||
pub strid: FT_UInt,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct FT_Var_Named_Style {
|
||||
pub coords: *mut FT_Fixed,
|
||||
pub strid: FT_UInt,
|
||||
pub psid: FT_UInt,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct FT_MM_Var {
|
||||
pub num_axis: FT_UInt,
|
||||
pub num_designs: FT_UInt,
|
||||
pub num_namedstyles: FT_UInt,
|
||||
pub axis: *mut FT_Var_Axis,
|
||||
pub namedstyle: *mut FT_Var_Named_Style,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unimplemented(error: FT_Error) -> bool {
|
||||
error == FT_Err_Unimplemented_Feature as FT_Error
|
||||
}
|
||||
|
||||
// Use dlsym to check for symbols. If not available. just return an unimplemented error.
|
||||
#[cfg(not(target_os = "android"))]
|
||||
macro_rules! ft_dyn_fn {
|
||||
($func_name:ident($($arg_name:ident:$arg_type:ty),*) -> FT_Error) => {
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn $func_name($($arg_name:$arg_type),*) -> FT_Error {
|
||||
extern "C" fn unimpl_func($(_:$arg_type),*) -> FT_Error {
|
||||
FT_Err_Unimplemented_Feature as FT_Error
|
||||
}
|
||||
lazy_static! {
|
||||
static ref func: unsafe extern "C" fn($($arg_type),*) -> FT_Error = {
|
||||
unsafe {
|
||||
let cname = CString::new(stringify!($func_name)).unwrap();
|
||||
let ptr = dlsym(RTLD_DEFAULT, cname.as_ptr());
|
||||
if !ptr.is_null() { mem::transmute(ptr) } else { unimpl_func }
|
||||
}
|
||||
};
|
||||
}
|
||||
(*func)($($arg_name),*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On Android, just statically link in the symbols...
|
||||
#[cfg(target_os = "android")]
|
||||
macro_rules! ft_dyn_fn {
|
||||
($($proto:tt)+) => { extern "C" { fn $($proto)+; } }
|
||||
}
|
||||
|
||||
ft_dyn_fn!(FT_Get_MM_Var(face: FT_Face, desc: *mut *mut FT_MM_Var) -> FT_Error);
|
||||
ft_dyn_fn!(FT_Done_MM_Var(library: FT_Library, desc: *mut FT_MM_Var) -> FT_Error);
|
||||
ft_dyn_fn!(FT_Set_Var_Design_Coordinates(face: FT_Face, num_vals: FT_UInt, vals: *mut FT_Fixed) -> FT_Error);
|
||||
|
||||
extern "C" {
|
||||
fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot);
|
||||
}
|
||||
|
||||
enum FontFile {
|
||||
Pathname(CString),
|
||||
Data(Arc<Vec<u8>>),
|
||||
}
|
||||
|
||||
struct FontFace {
|
||||
// Raw byte data has to live until the font is deleted, according to
|
||||
// https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_New_Memory_Face
|
||||
_bytes: Option<Arc<Vec<u8>>>,
|
||||
file: FontFile,
|
||||
index: u32,
|
||||
face: FT_Face,
|
||||
mm_var: *mut FT_MM_Var,
|
||||
}
|
||||
|
||||
impl Drop for FontFace {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if !self.mm_var.is_null() &&
|
||||
unimplemented(FT_Done_MM_Var((*(*self.face).glyph).library, self.mm_var)) {
|
||||
free(self.mm_var as _);
|
||||
}
|
||||
|
||||
FT_Done_Face(self.face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VariationFace(FT_Face);
|
||||
|
||||
impl Drop for VariationFace {
|
||||
fn drop(&mut self) {
|
||||
unsafe { FT_Done_Face(self.0) };
|
||||
}
|
||||
}
|
||||
|
||||
fn new_ft_face(font_key: &FontKey, lib: FT_Library, file: &FontFile, index: u32) -> Option<FT_Face> {
|
||||
unsafe {
|
||||
let mut face: FT_Face = ptr::null_mut();
|
||||
let result = match file {
|
||||
FontFile::Pathname(ref cstr) => FT_New_Face(
|
||||
lib,
|
||||
cstr.as_ptr(),
|
||||
index as FT_Long,
|
||||
&mut face,
|
||||
),
|
||||
FontFile::Data(ref bytes) => FT_New_Memory_Face(
|
||||
lib,
|
||||
bytes.as_ptr(),
|
||||
bytes.len() as FT_Long,
|
||||
index as FT_Long,
|
||||
&mut face,
|
||||
),
|
||||
};
|
||||
if succeeded(result) && !face.is_null() {
|
||||
Some(face)
|
||||
} else {
|
||||
warn!("WARN: webrender failed to load font");
|
||||
debug!("font={:?}, result={:?}", font_key, result);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FontContext {
|
||||
lib: FT_Library,
|
||||
faces: FastHashMap<FontKey, Face>,
|
||||
faces: FastHashMap<FontKey, FontFace>,
|
||||
variations: FastHashMap<(FontKey, Vec<FontVariation>), VariationFace>,
|
||||
lcd_extra_pixels: i64,
|
||||
}
|
||||
|
||||
|
@ -56,10 +187,6 @@ pub struct FontContext {
|
|||
// a given FontContext so it is safe to move the latter between threads.
|
||||
unsafe impl Send for FontContext {}
|
||||
|
||||
extern "C" {
|
||||
fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot);
|
||||
}
|
||||
|
||||
fn get_skew_bounds(bottom: i32, top: i32, skew_factor: f32) -> (f32, f32) {
|
||||
let skew_min = ((bottom as f32 + 0.5) * skew_factor).floor();
|
||||
let skew_max = ((top as f32 - 0.5) * skew_factor).ceil();
|
||||
|
@ -165,6 +292,7 @@ impl FontContext {
|
|||
Ok(FontContext {
|
||||
lib,
|
||||
faces: FastHashMap::default(),
|
||||
variations: FastHashMap::default(),
|
||||
lcd_extra_pixels,
|
||||
})
|
||||
} else {
|
||||
|
@ -181,72 +309,78 @@ impl FontContext {
|
|||
|
||||
pub fn add_raw_font(&mut self, font_key: &FontKey, bytes: Arc<Vec<u8>>, index: u32) {
|
||||
if !self.faces.contains_key(&font_key) {
|
||||
let mut face: FT_Face = ptr::null_mut();
|
||||
let result = unsafe {
|
||||
FT_New_Memory_Face(
|
||||
self.lib,
|
||||
bytes.as_ptr(),
|
||||
bytes.len() as FT_Long,
|
||||
index as FT_Long,
|
||||
&mut face,
|
||||
)
|
||||
};
|
||||
if succeeded(result) && !face.is_null() {
|
||||
self.faces.insert(
|
||||
*font_key,
|
||||
Face {
|
||||
face,
|
||||
_bytes: Some(bytes),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
warn!("WARN: webrender failed to load font");
|
||||
debug!("font={:?}", font_key);
|
||||
let file = FontFile::Data(bytes);
|
||||
if let Some(face) = new_ft_face(font_key, self.lib, &file, index) {
|
||||
self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_native_font(&mut self, font_key: &FontKey, native_font_handle: NativeFontHandle) {
|
||||
if !self.faces.contains_key(&font_key) {
|
||||
let mut face: FT_Face = ptr::null_mut();
|
||||
let pathname = CString::new(native_font_handle.pathname).unwrap();
|
||||
let result = unsafe {
|
||||
FT_New_Face(
|
||||
self.lib,
|
||||
pathname.as_ptr(),
|
||||
native_font_handle.index as FT_Long,
|
||||
&mut face,
|
||||
)
|
||||
};
|
||||
if succeeded(result) && !face.is_null() {
|
||||
self.faces.insert(
|
||||
*font_key,
|
||||
Face {
|
||||
face,
|
||||
_bytes: None,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
warn!("WARN: webrender failed to load font");
|
||||
debug!("font={:?}, path={:?}", font_key, pathname);
|
||||
let file = FontFile::Pathname(CString::new(native_font_handle.pathname).unwrap());
|
||||
let index = native_font_handle.index;
|
||||
if let Some(face) = new_ft_face(font_key, self.lib, &file, index) {
|
||||
self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_font(&mut self, font_key: &FontKey) {
|
||||
if let Some(face) = self.faces.remove(font_key) {
|
||||
let result = unsafe { FT_Done_Face(face.face) };
|
||||
assert!(succeeded(result));
|
||||
if let Some(_) = self.faces.remove(font_key) {
|
||||
self.variations.retain(|k, _| k.0 != *font_key);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_font_instance(&mut self, _instance: &FontInstance) {
|
||||
// This backend does not yet support variations, so there is nothing to do here.
|
||||
pub fn delete_font_instance(&mut self, instance: &FontInstance) {
|
||||
// Ensure we don't keep around excessive amounts of stale variations.
|
||||
if !instance.variations.is_empty() {
|
||||
self.variations.remove(&(instance.font_key, instance.variations.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
fn load_glyph(&self, font: &FontInstance, glyph: &GlyphKey) -> Option<(FT_GlyphSlot, f32)> {
|
||||
debug_assert!(self.faces.contains_key(&font.font_key));
|
||||
let face = self.faces.get(&font.font_key).unwrap();
|
||||
fn get_ft_face(&mut self, font: &FontInstance) -> Option<FT_Face> {
|
||||
if font.variations.is_empty() {
|
||||
return Some(self.faces.get(&font.font_key)?.face);
|
||||
}
|
||||
match self.variations.entry((font.font_key, font.variations.clone())) {
|
||||
Entry::Occupied(entry) => Some(entry.get().0),
|
||||
Entry::Vacant(entry) => unsafe {
|
||||
let normal_face = self.faces.get_mut(&font.font_key)?;
|
||||
if ((*normal_face.face).face_flags & (FT_FACE_FLAG_MULTIPLE_MASTERS as FT_Long)) == 0 {
|
||||
return Some(normal_face.face);
|
||||
}
|
||||
// Clone a new FT face and attempt to set the variation values on it.
|
||||
// Leave unspecified values at the defaults.
|
||||
let var_face = new_ft_face(&font.font_key, self.lib, &normal_face.file, normal_face.index)?;
|
||||
if !normal_face.mm_var.is_null() ||
|
||||
succeeded(FT_Get_MM_Var(normal_face.face, &mut normal_face.mm_var)) {
|
||||
let mm_var = normal_face.mm_var;
|
||||
let num_axis = (*mm_var).num_axis;
|
||||
let mut coords: Vec<FT_Fixed> = Vec::with_capacity(num_axis as usize);
|
||||
for i in 0 .. num_axis {
|
||||
let axis = (*mm_var).axis.offset(i as isize);
|
||||
let mut value = (*axis).def;
|
||||
for var in &font.variations {
|
||||
if var.tag as FT_ULong == (*axis).tag {
|
||||
value = (var.value * 65536.0 + 0.5) as FT_Fixed;
|
||||
value = cmp::min(value, (*axis).maximum);
|
||||
value = cmp::max(value, (*axis).minimum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
coords.push(value);
|
||||
}
|
||||
FT_Set_Var_Design_Coordinates(var_face, num_axis, coords.as_mut_ptr());
|
||||
}
|
||||
entry.insert(VariationFace(var_face));
|
||||
Some(var_face)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_glyph(&mut self, font: &FontInstance, glyph: &GlyphKey) -> Option<(FT_GlyphSlot, f32)> {
|
||||
let face = self.get_ft_face(font)?;
|
||||
|
||||
let mut load_flags = FT_LOAD_DEFAULT;
|
||||
let FontInstancePlatformOptions { mut hinting, .. } = font.platform_options.unwrap_or_default();
|
||||
|
@ -293,12 +427,12 @@ impl FontContext {
|
|||
let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
|
||||
let scale = font.oversized_scale_factor(x_scale, y_scale);
|
||||
let req_size = font.size.to_f64_px();
|
||||
let face_flags = unsafe { (*face.face).face_flags };
|
||||
let face_flags = unsafe { (*face).face_flags };
|
||||
let mut result = if (face_flags & (FT_FACE_FLAG_FIXED_SIZES as FT_Long)) != 0 &&
|
||||
(face_flags & (FT_FACE_FLAG_SCALABLE as FT_Long)) == 0 &&
|
||||
(load_flags & FT_LOAD_NO_BITMAP) == 0 {
|
||||
unsafe { FT_Set_Transform(face.face, ptr::null_mut(), ptr::null_mut()) };
|
||||
self.choose_bitmap_size(face.face, req_size * y_scale / scale)
|
||||
unsafe { FT_Set_Transform(face, ptr::null_mut(), ptr::null_mut()) };
|
||||
self.choose_bitmap_size(face, req_size * y_scale / scale)
|
||||
} else {
|
||||
let mut shape = font.transform.invert_scale(x_scale, y_scale);
|
||||
if font.flags.contains(FontInstanceFlags::FLIP_X) {
|
||||
|
@ -320,9 +454,9 @@ impl FontContext {
|
|||
yy: (shape.scale_y * 65536.0) as FT_Fixed,
|
||||
};
|
||||
unsafe {
|
||||
FT_Set_Transform(face.face, &mut ft_shape, ptr::null_mut());
|
||||
FT_Set_Transform(face, &mut ft_shape, ptr::null_mut());
|
||||
FT_Set_Char_Size(
|
||||
face.face,
|
||||
face,
|
||||
(req_size * x_scale / scale * 64.0 + 0.5) as FT_F26Dot6,
|
||||
(req_size * y_scale / scale * 64.0 + 0.5) as FT_F26Dot6,
|
||||
0,
|
||||
|
@ -332,11 +466,11 @@ impl FontContext {
|
|||
};
|
||||
|
||||
if succeeded(result) {
|
||||
result = unsafe { FT_Load_Glyph(face.face, glyph.index() as FT_UInt, load_flags as FT_Int32) };
|
||||
result = unsafe { FT_Load_Glyph(face, glyph.index() as FT_UInt, load_flags as FT_Int32) };
|
||||
};
|
||||
|
||||
if succeeded(result) {
|
||||
let slot = unsafe { (*face.face).glyph };
|
||||
let slot = unsafe { (*face).glyph };
|
||||
assert!(slot != ptr::null_mut());
|
||||
|
||||
if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) {
|
||||
|
@ -504,9 +638,9 @@ impl FontContext {
|
|||
}
|
||||
|
||||
pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
|
||||
let face = self.faces.get(&font_key).expect("Unknown font key!");
|
||||
let face = self.faces.get(&font_key)?.face;
|
||||
unsafe {
|
||||
let idx = FT_Get_Char_Index(face.face, ch as _);
|
||||
let idx = FT_Get_Char_Index(face, ch as _);
|
||||
if idx != 0 {
|
||||
Some(idx)
|
||||
} else {
|
||||
|
@ -823,6 +957,8 @@ impl FontContext {
|
|||
|
||||
impl Drop for FontContext {
|
||||
fn drop(&mut self) {
|
||||
self.variations.clear();
|
||||
self.faces.clear();
|
||||
unsafe {
|
||||
FT_Done_FreeType(self.lib);
|
||||
}
|
||||
|
|
|
@ -2036,7 +2036,7 @@ impl PrimitiveStore {
|
|||
let clip_chain = frame_state
|
||||
.clip_store
|
||||
.build_clip_chain_instance(
|
||||
prim_instance.clip_chain_id,
|
||||
prim_instance,
|
||||
local_rect,
|
||||
prim_local_clip_rect,
|
||||
prim_context.spatial_node_index,
|
||||
|
@ -3117,7 +3117,7 @@ impl PrimitiveInstance {
|
|||
let segment_clip_chain = frame_state
|
||||
.clip_store
|
||||
.build_clip_chain_instance(
|
||||
self.clip_chain_id,
|
||||
self,
|
||||
segment.local_rect.translate(&LayoutVector2D::new(prim_origin.x, prim_origin.y)),
|
||||
prim_local_clip_rect,
|
||||
prim_context.spatial_node_index,
|
||||
|
|
|
@ -53,6 +53,9 @@ struct PropertyKey {
|
|||
|
||||
bool operator==(const PropertyKey& rhs) const { return asBits == rhs.asBits; }
|
||||
bool operator!=(const PropertyKey& rhs) const { return asBits != rhs.asBits; }
|
||||
|
||||
MOZ_ALWAYS_INLINE bool isInt() const { return !!(asBits & JSID_TYPE_INT_BIT); }
|
||||
|
||||
} JS_HAZ_GC_POINTER;
|
||||
|
||||
} // namespace JS
|
||||
|
@ -91,6 +94,7 @@ static MOZ_ALWAYS_INLINE bool JSID_IS_INT(jsid id) {
|
|||
|
||||
static MOZ_ALWAYS_INLINE int32_t JSID_TO_INT(jsid id) {
|
||||
MOZ_ASSERT(JSID_IS_INT(id));
|
||||
MOZ_ASSERT(id.isInt());
|
||||
uint32_t bits = static_cast<uint32_t>(JSID_BITS(id)) >> 1;
|
||||
return static_cast<int32_t>(bits);
|
||||
}
|
||||
|
|
|
@ -502,9 +502,7 @@ nsresult AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) {
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// On Android, we need IgnoreRootScrollFrame for correct hit testing when
|
||||
// zoomed in or out.
|
||||
//
|
||||
// FIXME(emilio): But do we really want to override the other two flags?
|
||||
options = nsLayoutUtils::FrameForPointOption::IgnoreRootScrollFrame;
|
||||
options += nsLayoutUtils::FrameForPointOption::IgnoreRootScrollFrame;
|
||||
#endif
|
||||
|
||||
AutoWeakFrame ptFrame =
|
||||
|
|
|
@ -820,7 +820,7 @@ var gDownloadingPage = {
|
|||
this._pauseButton.setAttribute("tooltiptext",
|
||||
gUpdates.getAUSString("pauseButtonResume"));
|
||||
this._pauseButton.setAttribute("paused", "true");
|
||||
var p = u.selectedPatch.QueryInterface(Ci.nsIPropertyBag);
|
||||
var p = u.selectedPatch.QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
var status = p.getProperty("status");
|
||||
if (status) {
|
||||
let pausedStatus = gUpdates.getAUSString("downloadPausedStatus", [status]);
|
||||
|
|
|
@ -16,7 +16,6 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "XMLHttpRequest"]);
|
|||
const UPDATESERVICE_CID = Components.ID("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}");
|
||||
|
||||
const PREF_APP_UPDATE_ALTWINDOWTYPE = "app.update.altwindowtype";
|
||||
const PREF_APP_UPDATE_BACKGROUNDINTERVAL = "app.update.download.backgroundInterval";
|
||||
const PREF_APP_UPDATE_BACKGROUNDERRORS = "app.update.backgroundErrors";
|
||||
const PREF_APP_UPDATE_BACKGROUNDMAXERRORS = "app.update.backgroundMaxErrors";
|
||||
const PREF_APP_UPDATE_CANCELATIONS = "app.update.cancelations";
|
||||
|
@ -156,8 +155,6 @@ const NETWORK_ERROR_OFFLINE = 111;
|
|||
const HTTP_ERROR_OFFSET = 1000;
|
||||
|
||||
const DOWNLOAD_CHUNK_SIZE = 300000; // bytes
|
||||
const DOWNLOAD_BACKGROUND_INTERVAL = 600; // seconds
|
||||
const DOWNLOAD_FOREGROUND_INTERVAL = 0;
|
||||
|
||||
const UPDATE_WINDOW_NAME = "Update:Wizard";
|
||||
|
||||
|
@ -1330,8 +1327,6 @@ function Update(update) {
|
|||
this.unsupported = false;
|
||||
this.channel = "default";
|
||||
this.promptWaitTime = Services.prefs.getIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 43200);
|
||||
this.backgroundInterval = Services.prefs.getIntPref(PREF_APP_UPDATE_BACKGROUNDINTERVAL,
|
||||
DOWNLOAD_BACKGROUND_INTERVAL);
|
||||
|
||||
// Null <update>, assume this is a message container and do no
|
||||
// further initialization
|
||||
|
@ -1386,10 +1381,6 @@ function Update(update) {
|
|||
if (!isNaN(attr.value)) {
|
||||
this.promptWaitTime = parseInt(attr.value);
|
||||
}
|
||||
} else if (attr.name == "backgroundInterval") {
|
||||
if (!isNaN(attr.value)) {
|
||||
this.backgroundInterval = parseInt(attr.value);
|
||||
}
|
||||
} else if (attr.name == "unsupported") {
|
||||
this.unsupported = attr.value == "true";
|
||||
} else {
|
||||
|
@ -1420,9 +1411,6 @@ function Update(update) {
|
|||
this.displayVersion = this.appVersion;
|
||||
}
|
||||
|
||||
// Don't allow the background download interval to be greater than 10 minutes.
|
||||
this.backgroundInterval = Math.min(this.backgroundInterval, 600);
|
||||
|
||||
// The Update Name is either the string provided by the <update> element, or
|
||||
// the string: "<App Name> <Update App Version>"
|
||||
var name = "";
|
||||
|
@ -1528,7 +1516,6 @@ Update.prototype = {
|
|||
}
|
||||
var update = updates.createElementNS(URI_UPDATE_NS, "update");
|
||||
update.setAttribute("appVersion", this.appVersion);
|
||||
update.setAttribute("backgroundInterval", this.backgroundInterval);
|
||||
update.setAttribute("buildID", this.buildID);
|
||||
update.setAttribute("channel", this.channel);
|
||||
update.setAttribute("displayVersion", this.displayVersion);
|
||||
|
@ -3552,9 +3539,9 @@ Downloader.prototype = {
|
|||
|
||||
let patchFile = getUpdatesDir().clone();
|
||||
patchFile.append(FILE_UPDATE_MAR);
|
||||
update.QueryInterface(Ci.nsIPropertyBag);
|
||||
let interval = this.background ? update.getProperty("backgroundInterval")
|
||||
: DOWNLOAD_FOREGROUND_INTERVAL;
|
||||
|
||||
// The interval is 0 since there is no need to throttle downloads.
|
||||
let interval = 0;
|
||||
|
||||
LOG("Downloader:downloadUpdate - url: " + this._patch.URL + ", path: " +
|
||||
patchFile.path + ", interval: " + interval);
|
||||
|
@ -3903,6 +3890,7 @@ Downloader.prototype = {
|
|||
// downloading) and if at any point this was a foreground download
|
||||
// notify the user about the error. If the update was a background
|
||||
// update there is no notification since the user won't be expecting it.
|
||||
this._update.QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
if (!Services.wm.getMostRecentWindow(UPDATE_WINDOW_NAME) &&
|
||||
this._update.getProperty("foregroundDownload") == "true") {
|
||||
let prompter = Cc["@mozilla.org/updates/update-prompt;1"].
|
||||
|
|
|
@ -816,7 +816,6 @@ function setupPrefs() {
|
|||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 0);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_SILENT, false);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_DOORHANGER, false);
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_DOWNLOADBACKGROUNDINTERVAL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -915,10 +914,6 @@ function resetPrefs() {
|
|||
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_DOORHANGER)) {
|
||||
Services.prefs.clearUserPref(PREF_APP_UPDATE_DOORHANGER);
|
||||
}
|
||||
|
||||
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_DOWNLOADBACKGROUNDINTERVAL)) {
|
||||
Services.prefs.clearUserPref(PREF_APP_UPDATE_DOWNLOADBACKGROUNDINTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
function setupTimer(aTestTimeout) {
|
||||
|
|
|
@ -18,7 +18,6 @@ const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
|
|||
const PREF_APP_UPDATE_DOORHANGER = "app.update.doorhanger";
|
||||
const PREF_APP_UPDATE_DOWNLOADPROMPTATTEMPTS = "app.update.download.attempts";
|
||||
const PREF_APP_UPDATE_DOWNLOADPROMPTMAXATTEMPTS = "app.update.download.maxAttempts";
|
||||
const PREF_APP_UPDATE_DOWNLOADBACKGROUNDINTERVAL = "app.update.download.backgroundInterval";
|
||||
const PREF_APP_UPDATE_DISABLEDFORTESTING = "app.update.disabledForTesting";
|
||||
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
|
||||
const PREF_APP_UPDATE_LOG = "app.update.log";
|
||||
|
|
|
@ -118,7 +118,6 @@ function getRemoteUpdatesXMLString(aUpdates) {
|
|||
function getRemoteUpdateString(aUpdateProps, aPatches) {
|
||||
const updateProps = {
|
||||
appVersion: DEFAULT_UPDATE_VERSION,
|
||||
backgroundInterval: null,
|
||||
buildID: "20080811053724",
|
||||
custom1: null,
|
||||
custom2: null,
|
||||
|
@ -215,7 +214,6 @@ function getLocalUpdateString(aUpdateProps, aPatches) {
|
|||
set appVersion(val) {
|
||||
this._appVersion = val;
|
||||
},
|
||||
backgroundInterval: null,
|
||||
buildID: "20080811053724",
|
||||
channel: gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_CHANNEL),
|
||||
custom1: null,
|
||||
|
@ -310,8 +308,6 @@ function getUpdateString(aUpdateProps) {
|
|||
let detailsURL = "detailsURL=\"" + aUpdateProps.detailsURL + "\" ";
|
||||
let promptWaitTime = aUpdateProps.promptWaitTime ?
|
||||
"promptWaitTime=\"" + aUpdateProps.promptWaitTime + "\" " : "";
|
||||
let backgroundInterval = aUpdateProps.backgroundInterval ?
|
||||
"backgroundInterval=\"" + aUpdateProps.backgroundInterval + "\" " : "";
|
||||
let custom1 = aUpdateProps.custom1 ? aUpdateProps.custom1 + " " : "";
|
||||
let custom2 = aUpdateProps.custom2 ? aUpdateProps.custom2 + " " : "";
|
||||
let buildID = "buildID=\"" + aUpdateProps.buildID + "\"";
|
||||
|
@ -322,7 +318,6 @@ function getUpdateString(aUpdateProps) {
|
|||
appVersion +
|
||||
detailsURL +
|
||||
promptWaitTime +
|
||||
backgroundInterval +
|
||||
custom1 +
|
||||
custom2 +
|
||||
buildID;
|
||||
|
|
|
@ -15,10 +15,6 @@ function run_test() {
|
|||
setUpdateURL(gURLData + gHTTPHandlerPath);
|
||||
setUpdateChannel("test_channel");
|
||||
|
||||
// This test expects that the app.update.download.backgroundInterval
|
||||
// preference doesn't already exist.
|
||||
Services.prefs.deleteBranch("app.update.download.backgroundInterval");
|
||||
|
||||
standardInit();
|
||||
executeSoon(run_test_pt01);
|
||||
}
|
||||
|
@ -67,7 +63,6 @@ function run_test_pt02() {
|
|||
buildID: "20080811053724",
|
||||
detailsURL: "http://details/",
|
||||
promptWaitTime: "345600",
|
||||
backgroundInterval: "1200",
|
||||
custom1: "custom1_attr=\"custom1 value\"",
|
||||
custom2: "custom2_attr=\"custom2 value\""};
|
||||
let updates = getRemoteUpdateString(updateProps, patches);
|
||||
|
@ -92,7 +87,7 @@ function check_test_pt02() {
|
|||
|
||||
Assert.equal(gUpdateCount, 1,
|
||||
"the update count" + MSG_SHOULD_EQUAL);
|
||||
let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount).QueryInterface(Ci.nsIPropertyBag);
|
||||
let bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount).QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
Assert.equal(bestUpdate.type, "minor",
|
||||
"the update type attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(bestUpdate.name, "Minor Test",
|
||||
|
@ -107,9 +102,6 @@ function check_test_pt02() {
|
|||
"the update detailsURL attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(bestUpdate.promptWaitTime, "345600",
|
||||
"the update promptWaitTime attribute" + MSG_SHOULD_EQUAL);
|
||||
// The default and maximum value for backgroundInterval is 600
|
||||
Assert.equal(bestUpdate.getProperty("backgroundInterval"), "600",
|
||||
"the update backgroundInterval attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(bestUpdate.serviceURL, gURLData + gHTTPHandlerPath + "?force=1",
|
||||
"the update serviceURL attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(bestUpdate.channel, "test_channel",
|
||||
|
|
|
@ -12,10 +12,6 @@ function run_test() {
|
|||
|
||||
setUpdateChannel("test_channel");
|
||||
|
||||
// This test expects that the app.update.download.backgroundInterval
|
||||
// preference doesn't already exist.
|
||||
Services.prefs.deleteBranch("app.update.download.backgroundInterval");
|
||||
|
||||
let patchProps = {type: "partial",
|
||||
url: "http://partial/",
|
||||
size: "86",
|
||||
|
@ -35,7 +31,6 @@ function run_test() {
|
|||
channel: "test_channel",
|
||||
foregroundDownload: "true",
|
||||
promptWaitTime: "345600",
|
||||
backgroundInterval: "300",
|
||||
previousAppVersion: "3.0",
|
||||
custom1: "custom1_attr=\"custom1 value\"",
|
||||
custom2: "custom2_attr=\"custom2 value\""};
|
||||
|
@ -72,7 +67,7 @@ function run_test() {
|
|||
"the update manager updateCount attribute" + MSG_SHOULD_EQUAL);
|
||||
|
||||
debugDump("checking the activeUpdate properties");
|
||||
let update = gUpdateManager.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
|
||||
let update = gUpdateManager.getUpdateAt(0).QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
Assert.equal(update.state, STATE_SUCCEEDED,
|
||||
"the update state attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.type, "major",
|
||||
|
@ -100,8 +95,6 @@ function run_test() {
|
|||
"the update channel attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.promptWaitTime, "345600",
|
||||
"the update promptWaitTime attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.getProperty("backgroundInterval"), "300",
|
||||
"the update backgroundInterval attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.previousAppVersion, "3.0",
|
||||
"the update previousAppVersion attribute" + MSG_SHOULD_EQUAL);
|
||||
// Custom attributes
|
||||
|
@ -124,7 +117,7 @@ function run_test() {
|
|||
"the update patch state attribute" + MSG_SHOULD_EQUAL);
|
||||
|
||||
debugDump("checking the first update properties");
|
||||
update = gUpdateManager.getUpdateAt(1).QueryInterface(Ci.nsIPropertyBag);
|
||||
update = gUpdateManager.getUpdateAt(1).QueryInterface(Ci.nsIWritablePropertyBag);
|
||||
Assert.equal(update.state, STATE_FAILED,
|
||||
"the update state attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.name, "Existing",
|
||||
|
@ -151,9 +144,6 @@ function run_test() {
|
|||
"the update channel attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.promptWaitTime, "691200",
|
||||
"the update promptWaitTime attribute" + MSG_SHOULD_EQUAL);
|
||||
// The default and maximum value for backgroundInterval is 600
|
||||
Assert.equal(update.getProperty("backgroundInterval"), "600",
|
||||
"the update backgroundInterval attribute" + MSG_SHOULD_EQUAL);
|
||||
Assert.equal(update.previousAppVersion, null,
|
||||
"the update previousAppVersion attribute" + MSG_SHOULD_EQUAL);
|
||||
// Custom attributes
|
||||
|
|
|
@ -262,23 +262,3 @@ popupnotificationcontent {
|
|||
|
||||
%include ../../shared/notification-popup.inc.css
|
||||
|
||||
/* :::::: autoscroll popup ::::: */
|
||||
|
||||
.autoscroller {
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-image: url("chrome://global/skin/icons/autoscroll.svg");
|
||||
background-size: contain;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="NS"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-vertical.svg");
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="EW"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-horizontal.svg");
|
||||
}
|
||||
|
||||
|
|
|
@ -250,28 +250,6 @@ popupnotificationcontent {
|
|||
|
||||
%include ../../shared/notification-popup.inc.css
|
||||
|
||||
/* :::::: autoscroll popup ::::: */
|
||||
|
||||
.autoscroller {
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-image: url("chrome://global/skin/icons/autoscroll.svg");
|
||||
background-size: contain;
|
||||
background-color: transparent;
|
||||
background-position: right top;
|
||||
background-repeat: no-repeat;
|
||||
-moz-appearance: none;
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="NS"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-vertical.svg");
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="EW"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-horizontal.svg");
|
||||
}
|
||||
|
||||
/* autorepeatbuttons in menus */
|
||||
|
||||
.popup-internal-box > .scrollbutton-up,
|
||||
|
|
|
@ -28,6 +28,27 @@
|
|||
height: 20px;
|
||||
}
|
||||
|
||||
/* Autoscroll popup */
|
||||
|
||||
.autoscroller {
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-image: url("chrome://global/skin/icons/autoscroll.svg");
|
||||
background-size: contain;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
-moz-appearance: none;
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="NS"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-vertical.svg");
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="EW"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-horizontal.svg");
|
||||
}
|
||||
|
||||
/* Panel footers */
|
||||
|
||||
.panel-footer {
|
||||
|
|
|
@ -267,23 +267,3 @@ popupnotificationcontent {
|
|||
|
||||
%include ../../shared/notification-popup.inc.css
|
||||
|
||||
/* :::::: autoscroll popup ::::: */
|
||||
|
||||
.autoscroller {
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-image: url("chrome://global/skin/icons/autoscroll.svg");
|
||||
background-size: contain;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="NS"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-vertical.svg");
|
||||
}
|
||||
|
||||
.autoscroller[scrolldir="EW"] {
|
||||
background-image: url("chrome://global/skin/icons/autoscroll-horizontal.svg");
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче