Merge inbound to m-c on a CLOSED TREE

This commit is contained in:
Wes Kocher 2013-11-18 18:30:47 -08:00
commit 227b9b8a2c
255 changed files with 3711 additions and 7218 deletions

View File

@ -6,24 +6,9 @@
#include "nsISupports.idl"
interface nsIEditor;
[scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)]
[scriptable, uuid(93d0ba57-0d20-49d1-aede-8fde6699855d)]
interface nsIAccessibleEditableText : nsISupports
{
/**
* Sets the attributes for the text between the two given indices. The old
* attributes are replaced by the new list of attributes. For example,
* sets font styles, such as italic, bold...
*
* @param startPos - start index of the text whose attributes are modified.
* @param endPos - end index of the text whose attributes are modified.
* @param attributes - set of attributes that replaces the old list of
* attributes of the specified text portion.
*/
void setAttributes (in long startPos, in long endPos,
in nsISupports attributes);
/**
* Replaces the text represented by this object by the given text.
*/
@ -35,7 +20,8 @@ interface nsIAccessibleEditableText : nsISupports
* @param text - text that is inserted.
* @param position - index at which to insert the text.
*/
void insertText (in AString text, in long position);
[binaryname(ScriptableInsertText)]
void insertText(in AString text, in long position);
/**
* Copies the text range into the clipboard.
@ -43,7 +29,8 @@ interface nsIAccessibleEditableText : nsISupports
* @param startPos - start index of the text to moved into the clipboard.
* @param endPos - end index of the text to moved into the clipboard.
*/
void copyText (in long startPos, in long endPos);
[binaryname(ScriptableCopyText)]
void copyText(in long startPos, in long endPos);
/**
* Deletes a range of text and copies it to the clipboard.
@ -51,7 +38,8 @@ interface nsIAccessibleEditableText : nsISupports
* @param startPos - start index of the text to be deleted.
* @param endOffset - end index of the text to be deleted.
*/
void cutText (in long startPos, in long endPos);
[binaryname(ScriptableCutText)]
void cutText(in long startPos, in long endPos);
/**
* Deletes a range of text.
@ -59,7 +47,8 @@ interface nsIAccessibleEditableText : nsISupports
* @param startPos - start index of the text to be deleted.
* @param endPos - end index of the text to be deleted.
*/
void deleteText (in long startPos, in long endPos);
[binaryname(ScriptableDeleteText)]
void deleteText(in long startPos, in long endPos);
/**
* Pastes text from the clipboard.
@ -67,5 +56,6 @@ interface nsIAccessibleEditableText : nsISupports
* @param position - index at which to insert the text from the system
* clipboard into the text represented by this object.
*/
void pasteText (in long position);
[binaryname(ScriptablePasteText)]
void pasteText(in long position);
};

View File

@ -11,7 +11,7 @@ typedef long AccessibleTextBoundary;
interface nsIAccessible;
interface nsIPersistentProperties;
[scriptable, uuid(43d81eb0-1215-4dc4-9226-a4355bd2d20d)]
[scriptable, uuid(1e63dd8b-173d-4a68-8ade-fd671abbe1ee)]
interface nsIAccessibleText : nsISupports
{
// In parameters for character offsets:
@ -32,6 +32,7 @@ interface nsIAccessibleText : nsISupports
* The current current caret offset.
* If set < 0 then caret will be placed at the end of the text
*/
[binaryname(ScriptableCaretOffset)]
attribute long caretOffset;
readonly attribute long characterCount;
@ -168,6 +169,7 @@ interface nsIAccessibleText : nsISupports
* @param scrollType defines how to scroll (see nsIAccessibleScrollType for
* available constants)
*/
[binaryname(ScriptableScrollSubstringTo)]
void scrollSubstringTo(in long startIndex, in long endIndex,
in unsigned long scrollType);
@ -183,6 +185,7 @@ interface nsIAccessibleText : nsISupports
* @param x defines the x coordinate
* @param y defines the y coordinate
*/
[binaryname(ScriptableScrollSubstringToPoint)]
void scrollSubstringToPoint(in long startIndex, in long endIndex,
in unsigned long coordinateType,
in long x, in long y);

View File

@ -157,6 +157,7 @@ static const gchar* getNameCB (AtkObject *aAtkObj);
const gchar* getDescriptionCB (AtkObject *aAtkObj);
static AtkRole getRoleCB(AtkObject *aAtkObj);
static AtkAttributeSet* getAttributesCB(AtkObject *aAtkObj);
static const gchar* GetLocaleCB(AtkObject*);
static AtkObject* getParentCB(AtkObject *aAtkObj);
static gint getChildCountCB(AtkObject *aAtkObj);
static AtkObject* refChildCB(AtkObject *aAtkObj, gint aChildIndex);
@ -489,6 +490,7 @@ classInitCB(AtkObjectClass *aClass)
aClass->get_index_in_parent = getIndexInParentCB;
aClass->get_role = getRoleCB;
aClass->get_attributes = getAttributesCB;
aClass->get_object_locale = GetLocaleCB;
aClass->ref_state_set = refStateSetCB;
aClass->ref_relation_set = refRelationSetCB;
@ -754,6 +756,18 @@ getAttributesCB(AtkObject *aAtkObj)
return accWrap ? GetAttributeSet(accWrap) : nullptr;
}
const gchar*
GetLocaleCB(AtkObject* aAtkObj)
{
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (!accWrap)
return nullptr;
nsAutoString locale;
accWrap->Language(locale);
return AccessibleWrap::ReturnString(locale);
}
AtkObject *
getParentCB(AtkObject *aAtkObj)
{
@ -982,6 +996,7 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
{
a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible();
if (rootAccWrap && rootAccWrap->mActivated) {
atk_focus_tracker_notify(atkObj);
// Fire state change event for focus
atk_object_notify_state_change(atkObj, ATK_STATE_FOCUSED, true);
return NS_OK;
@ -1167,6 +1182,7 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
break;
case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
atk_focus_tracker_notify(atkObj); // fire extra focus event
atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, true);
atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, true);
break;

View File

@ -7,7 +7,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "HyperTextAccessible-inl.h"
#include "nsMai.h"
#include "nsString.h"
@ -28,7 +28,7 @@ setTextContentsCB(AtkEditableText *aText, const gchar *aString)
return;
NS_ConvertUTF8toUTF16 strContent(aString);
text->SetTextContents(strContent);
text->ReplaceText(strContent);
}
static void

View File

@ -26,7 +26,7 @@ getLinkCB(AtkHypertext *aText, gint aLinkIndex)
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, nullptr);
Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
Accessible* hyperLink = hyperText->LinkAt(aLinkIndex);
if (!hyperLink)
return nullptr;
@ -49,7 +49,7 @@ getLinkCountCB(AtkHypertext *aText)
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, -1);
return hyperText->GetLinkCount();
return hyperText->LinkCount();
}
static gint
@ -62,11 +62,7 @@ getLinkIndexCB(AtkHypertext *aText, gint aCharIndex)
HyperTextAccessible* hyperText = accWrap->AsHyperText();
NS_ENSURE_TRUE(hyperText, -1);
int32_t index = -1;
nsresult rv = hyperText->GetLinkIndexAtOffset(aCharIndex, &index);
NS_ENSURE_SUCCESS(rv, -1);
return index;
return hyperText->LinkIndexAtOffset(aCharIndex);
}
}

View File

@ -7,7 +7,7 @@
#include "InterfaceInitFuncs.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible.h"
#include "HyperTextAccessible-inl.h"
#include "nsMai.h"
#include "nsIAccessibleTypes.h"
@ -43,8 +43,7 @@ getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset)
return nullptr;
nsAutoString autoStr;
nsresult rv = text->GetText(aStartOffset, aEndOffset, autoStr);
NS_ENSURE_SUCCESS(rv, nullptr);
text->TextSubstring(aStartOffset, aEndOffset, autoStr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
@ -68,18 +67,14 @@ getTextAfterOffsetCB(AtkText *aText, gint aOffset,
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextAfterOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
text->TextAfterOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gchar*
@ -97,14 +92,10 @@ getTextAtOffsetCB(AtkText *aText, gint aOffset,
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextAtOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
text->TextAtOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
@ -148,19 +139,16 @@ getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
if (!text || !text->IsTextRole())
return nullptr;
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv =
text->GetTextBeforeOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
nsAutoString autoStr;
int32_t startOffset = 0, endOffset = 0;
text->TextBeforeOffset(aOffset, aBoundaryType,
&startOffset, &endOffset, autoStr);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
ConvertTexttoAsterisks(accWrap, autoStr);
NS_ConvertUTF16toUTF8 cautoStr(autoStr);
return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
}
static gint
@ -174,9 +162,7 @@ getCaretOffsetCB(AtkText *aText)
if (!text || !text->IsTextRole())
return 0;
int32_t offset;
nsresult rv = text->GetCaretOffset(&offset);
return (NS_FAILED(rv)) ? 0 : static_cast<gint>(offset);
return static_cast<gint>(text->CaretOffset());
}
static AtkAttributeSet*
@ -195,17 +181,14 @@ getRunAttributesCB(AtkText *aText, gint aOffset,
if (!text || !text->IsTextRole())
return nullptr;
nsCOMPtr<nsIPersistentProperties> attributes;
int32_t startOffset = 0, endOffset = 0;
nsresult rv = text->GetTextAttributes(false, aOffset,
&startOffset, &endOffset,
getter_AddRefs(attributes));
NS_ENSURE_SUCCESS(rv, nullptr);
int32_t startOffset = 0, endOffset = 0;
nsCOMPtr<nsIPersistentProperties> attributes =
text->TextAttributes(false, aOffset, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return ConvertToAtkAttributeSet(attributes);
return ConvertToAtkAttributeSet(attributes);
}
static AtkAttributeSet*
@ -219,12 +202,8 @@ getDefaultAttributesCB(AtkText *aText)
if (!text || !text->IsTextRole())
return nullptr;
nsCOMPtr<nsIPersistentProperties> attributes;
nsresult rv = text->GetDefaultTextAttributes(getter_AddRefs(attributes));
if (NS_FAILED(rv))
return nullptr;
return ConvertToAtkAttributeSet(attributes);
nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
return ConvertToAtkAttributeSet(attributes);
}
static void
@ -241,27 +220,17 @@ getCharacterExtentsCB(AtkText *aText, gint aOffset,
if (!text || !text->IsTextRole())
return;
int32_t extY = 0, extX = 0;
int32_t extWidth = 0, extHeight = 0;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN)
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
#ifdef DEBUG
nsresult rv =
#endif
text->GetCharacterExtents(aOffset, &extX, &extY,
&extWidth, &extHeight,
geckoCoordType);
*aX = extX;
*aY = extY;
*aWidth = extWidth;
*aHeight = extHeight;
NS_ASSERTION(NS_SUCCEEDED(rv),
"MaiInterfaceText::GetCharacterExtents, failed\n");
nsIntRect rect = text->CharBounds(aOffset, geckoCoordType);
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;
*aHeight = rect.height;
}
static void
@ -276,28 +245,17 @@ getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset,
if (!text || !text->IsTextRole())
return;
int32_t extY = 0, extX = 0;
int32_t extWidth = 0, extHeight = 0;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN)
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
#ifdef DEBUG
nsresult rv =
#endif
text->GetRangeExtents(aStartOffset, aEndOffset,
&extX, &extY,
&extWidth, &extHeight,
geckoCoordType);
aRect->x = extX;
aRect->y = extY;
aRect->width = extWidth;
aRect->height = extHeight;
NS_ASSERTION(NS_SUCCEEDED(rv),
"MaiInterfaceText::GetRangeExtents, failed\n");
nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
aRect->x = rect.x;
aRect->y = rect.y;
aRect->width = rect.width;
aRect->height = rect.height;
}
static gint
@ -325,15 +283,11 @@ getOffsetAtPointCB(AtkText *aText,
if (!text || !text->IsTextRole())
return -1;
int32_t offset = 0;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN)
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
text->GetOffsetAtPoint(aX, aY, geckoCoordType, &offset);
return static_cast<gint>(offset);
return static_cast<gint>(
text->OffsetAtPoint(aX, aY,
(aCoords == ATK_XY_SCREEN ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
}
static gint
@ -347,10 +301,7 @@ getTextSelectionCountCB(AtkText *aText)
if (!text || !text->IsTextRole())
return 0;
int32_t selectionCount;
nsresult rv = text->GetSelectionCount(&selectionCount);
return NS_FAILED(rv) ? 0 : selectionCount;
return text->SelectionCount();
}
static gchar*
@ -365,15 +316,12 @@ getTextSelectionCB(AtkText *aText, gint aSelectionNum,
if (!text || !text->IsTextRole())
return nullptr;
int32_t startOffset = 0, endOffset = 0;
nsresult rv = text->GetSelectionBounds(aSelectionNum,
&startOffset, &endOffset);
int32_t startOffset = 0, endOffset = 0;
text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ENSURE_SUCCESS(rv, nullptr);
return getTextCB(aText, *aStartOffset, *aEndOffset);
}
@ -389,11 +337,9 @@ addTextSelectionCB(AtkText *aText,
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
return FALSE;
nsresult rv = text->AddSelection(aStartOffset, aEndOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
return text->AddToSelection(aStartOffset, aEndOffset);
}
static gboolean
@ -406,11 +352,9 @@ removeTextSelectionCB(AtkText *aText,
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
return FALSE;
nsresult rv = text->RemoveSelection(aSelectionNum);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
return text->RemoveFromSelection(aSelectionNum);
}
static gboolean
@ -423,11 +367,9 @@ setTextSelectionCB(AtkText *aText, gint aSelectionNum,
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
return FALSE;
nsresult rv = text->SetSelectionBounds(aSelectionNum,
aStartOffset, aEndOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
}
static gboolean
@ -438,11 +380,11 @@ setCaretOffsetCB(AtkText *aText, gint aOffset)
return FALSE;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return false;
if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset))
return FALSE;
nsresult rv = text->SetCaretOffset(aOffset);
return NS_SUCCEEDED(rv) ? TRUE : FALSE;
text->SetCaretOffset(aOffset);
return TRUE;
}
}

View File

@ -15,10 +15,6 @@
using namespace mozilla;
using namespace mozilla::a11y;
// Defines the number of selection add/remove events in the queue when they
// aren't packed into single selection within event.
const unsigned int kSelChangeCountToPack = 5;
////////////////////////////////////////////////////////////////////////////////
// NotificationCollector
////////////////////////////////////////////////////////////////////////////////

View File

@ -130,8 +130,8 @@ SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent)
if (!caretCntr)
return;
int32_t caretOffset = -1;
if (NS_SUCCEEDED(caretCntr->GetCaretOffset(&caretOffset)) && caretOffset != -1) {
int32_t caretOffset = caretCntr->CaretOffset();
if (caretOffset != -1) {
nsRefPtr<AccCaretMoveEvent> caretMoveEvent =
new AccCaretMoveEvent(caretCntr, caretOffset, aEvent->FromUserInput());
nsEventShell::FireEvent(caretMoveEvent);

View File

@ -29,7 +29,7 @@ if CONFIG['MOZ_DEBUG']:
'Logging.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'AccCollector.cpp',
'AccEvent.cpp',
'AccGroupInfo.cpp',
@ -56,7 +56,7 @@ SOURCES += [
]
if a11y_log:
SOURCES += [
UNIFIED_SOURCES += [
'Logging.cpp',
]

View File

@ -305,7 +305,7 @@ nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult)
Accessible* root = GetActiveRoot();
while (true) {
Accessible* curPosition = tempPosition;
HyperTextAccessible* text;
HyperTextAccessible* text = nullptr;
// Find the nearest text node using a preorder traversal starting from
// the current node.
if (!(text = tempPosition->AsHyperText())) {
@ -370,9 +370,8 @@ nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult)
nsAutoString unusedText;
int32_t newStart = 0, newEnd = 0, currentEnd = tempEnd;
text->GetTextAtOffset(tempEnd, endBoundary, &newStart, &tempEnd, unusedText);
text->GetTextBeforeOffset(tempEnd, startBoundary, &newStart, &newEnd,
unusedText);
text->TextAtOffset(tempEnd, endBoundary, &newStart, &tempEnd, unusedText);
text->TextBeforeOffset(tempEnd, startBoundary, &newStart, &newEnd, unusedText);
int32_t potentialStart = newEnd == tempEnd ? newStart : newEnd;
tempStart = potentialStart > tempStart ? potentialStart : currentEnd;
@ -494,15 +493,14 @@ nsAccessiblePivot::MovePreviousByText(TextBoundaryType aBoundary, bool* aResult)
nsAutoString unusedText;
int32_t newStart = 0, newEnd = 0, currentStart = tempStart, potentialEnd = 0;
text->GetTextBeforeOffset(tempStart, startBoundary, &newStart, &newEnd,
unusedText);
text->TextBeforeOffset(tempStart, startBoundary, &newStart, &newEnd, unusedText);
if (newStart < tempStart)
tempStart = newEnd >= currentStart ? newStart : newEnd;
else // XXX: In certain odd cases newStart is equal to tempStart
text->GetTextBeforeOffset(tempStart - 1, startBoundary, &newStart,
&tempStart, unusedText);
text->GetTextAtOffset(tempStart, endBoundary, &newStart, &potentialEnd,
unusedText);
text->TextBeforeOffset(tempStart - 1, startBoundary, &newStart,
&tempStart, unusedText);
text->TextAtOffset(tempStart, endBoundary, &newStart, &potentialEnd,
unusedText);
tempEnd = potentialEnd < tempEnd ? potentialEnd : currentStart;
// The offset range we've obtained might have embedded characters in it,

View File

@ -0,0 +1,164 @@
/* -*- Mode: C++; tab-width: 2; 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/. */
#ifndef mozilla_a11y_HyperTextAccessible_inl_h__
#define mozilla_a11y_HyperTextAccessible_inl_h__
#include "HyperTextAccessible.h"
#include "nsAccUtils.h"
#include "nsIClipboard.h"
#include "nsIEditor.h"
#include "nsIPersistentProperties2.h"
#include "nsIPlaintextEditor.h"
namespace mozilla {
namespace a11y {
inline bool
HyperTextAccessible::IsValidOffset(int32_t aOffset)
{
int32_t offset = ConvertMagicOffset(aOffset);
return offset >= 0 && offset <= static_cast<int32_t>(CharacterCount());
}
inline bool
HyperTextAccessible::IsValidRange(int32_t aStartOffset, int32_t aEndOffset)
{
int32_t startOffset = ConvertMagicOffset(aStartOffset);
if (startOffset < 0)
return false;
int32_t endOffset = ConvertMagicOffset(aEndOffset);
if (endOffset < 0 || startOffset > endOffset)
return false;
return endOffset <= static_cast<int32_t>(CharacterCount());
}
inline nsIntRect
HyperTextAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType)
{
nsIntRect bounds;
GetPosAndText(aStartOffset, aEndOffset, nullptr, nullptr, &bounds);
nsAccUtils::ConvertScreenCoordsTo(&bounds.x, &bounds.y, aCoordType, this);
return bounds;
}
inline bool
HyperTextAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
{
Selection* domSel = DOMSelection();
return domSel &&
SetSelectionBoundsAt(domSel->GetRangeCount(), aStartOffset, aEndOffset);
}
inline void
HyperTextAccessible::ReplaceText(const nsAString& aText)
{
int32_t numChars = CharacterCount();
if (numChars != 0)
DeleteText(0, numChars);
InsertText(aText, 0);
}
inline void
HyperTextAccessible::InsertText(const nsAString& aText, int32_t aPosition)
{
nsCOMPtr<nsIEditor> editor = GetEditor();
nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
if (peditor) {
SetSelectionRange(aPosition, aPosition);
peditor->InsertText(aText);
}
}
inline void
HyperTextAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
{
nsCOMPtr<nsIEditor> editor = GetEditor();
if (editor) {
SetSelectionRange(aStartPos, aEndPos);
editor->Copy();
}
}
inline void
HyperTextAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
{
nsCOMPtr<nsIEditor> editor = GetEditor();
if (editor) {
SetSelectionRange(aStartPos, aEndPos);
editor->Cut();
}
}
inline void
HyperTextAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
{
nsCOMPtr<nsIEditor> editor = GetEditor();
if (editor) {
SetSelectionRange(aStartPos, aEndPos);
editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
}
}
inline void
HyperTextAccessible::PasteText(int32_t aPosition)
{
nsCOMPtr<nsIEditor> editor = GetEditor();
if (editor) {
SetSelectionRange(aPosition, aPosition);
editor->Paste(nsIClipboard::kGlobalClipboard);
}
}
inline int32_t
HyperTextAccessible::ConvertMagicOffset(int32_t aOffset)
{
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
return CharacterCount();
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
return CaretOffset();
return aOffset;
}
inline int32_t
HyperTextAccessible::AdjustCaretOffset(int32_t aOffset) const
{
// It is the same character offset when the caret is visually at the very
// end of a line or the start of a new line (soft line break). Getting text
// at the line should provide the line with the visual caret, otherwise
// screen readers will announce the wrong line as the user presses up or
// down arrow and land at the end of a line.
if (aOffset > 0) {
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
if (frameSelection &&
frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
return aOffset - 1;
}
}
return aOffset;
}
inline Selection*
HyperTextAccessible::DOMSelection() const
{
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
return frameSelection ?
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL) :
nullptr;
}
} // namespace a11y
} // namespace mozilla
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,9 @@
#ifndef mozilla_a11y_HyperTextAccessible_h__
#define mozilla_a11y_HyperTextAccessible_h__
#include "nsIAccessibleText.h"
#include "nsIAccessibleHyperText.h"
#include "nsIAccessibleEditableText.h"
#include "AccessibleWrap.h"
#include "nsIAccessibleTypes.h"
#include "xpcAccessibleHyperText.h"
#include "nsFrameSelection.h"
#include "nsISelectionController.h"
@ -35,18 +33,13 @@ const PRUnichar kForcedNewLineChar = '\n';
* Special Accessible that knows how contain both text and embedded objects
*/
class HyperTextAccessible : public AccessibleWrap,
public nsIAccessibleText,
public nsIAccessibleHyperText,
public nsIAccessibleEditableText
public xpcAccessibleHyperText
{
public:
HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
virtual ~HyperTextAccessible() { }
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETEXT
NS_DECL_NSIACCESSIBLEHYPERTEXT
NS_DECL_NSIACCESSIBLEEDITABLETEXT
// Accessible
virtual int32_t GetLevelInternal();
@ -59,13 +52,13 @@ public:
// HyperTextAccessible (static helper method)
// Convert content offset to rendered text offset
// Convert content offset to rendered text offset
nsresult ContentToRenderedOffset(nsIFrame *aFrame, int32_t aContentOffset,
uint32_t *aRenderedOffset);
uint32_t *aRenderedOffset) const;
// Convert rendered text offset to content offset
nsresult RenderedToContentOffset(nsIFrame *aFrame, uint32_t aRenderedOffset,
int32_t *aContentOffset);
int32_t *aContentOffset) const;
//////////////////////////////////////////////////////////////////////////////
// HyperLinkAccessible
@ -73,15 +66,13 @@ public:
/**
* Return link count within this hypertext accessible.
*/
uint32_t GetLinkCount()
{
return EmbeddedChildCount();
}
uint32_t LinkCount()
{ return EmbeddedChildCount(); }
/**
* Return link accessible at the given index.
*/
Accessible* GetLinkAt(uint32_t aIndex)
Accessible* LinkAt(uint32_t aIndex)
{
return GetEmbeddedChildAt(aIndex);
}
@ -89,7 +80,7 @@ public:
/**
* Return index for the given link accessible.
*/
int32_t GetLinkIndex(Accessible* aLink)
int32_t LinkIndexOf(Accessible* aLink)
{
return GetIndexOfEmbeddedChild(aLink);
}
@ -97,10 +88,10 @@ public:
/**
* Return link accessible at the given text offset.
*/
int32_t GetLinkIndexAtOffset(uint32_t aOffset)
int32_t LinkIndexAtOffset(uint32_t aOffset)
{
Accessible* child = GetChildAtOffset(aOffset);
return child ? GetLinkIndex(child) : -1;
return child ? LinkIndexOf(child) : -1;
}
//////////////////////////////////////////////////////////////////////////////
@ -134,7 +125,7 @@ public:
Accessible* DOMPointToHypertextOffset(nsINode *aNode,
int32_t aNodeOffset,
int32_t* aHypertextOffset,
bool aIsEndOffset = false);
bool aIsEndOffset = false) const;
/**
* Turn a start and end hypertext offsets into DOM range.
@ -208,6 +199,37 @@ public:
bool GetCharAt(int32_t aOffset, EGetTextType aShift, nsAString& aChar,
int32_t* aStartOffset = nullptr, int32_t* aEndOffset = nullptr);
/**
* Return text between given offsets.
*/
void TextSubstring(int32_t aStartOffset, int32_t aEndOffset, nsAString& aText);
/**
* Return text before/at/after the given offset corresponding to
* the boundary type.
*/
void TextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset, int32_t* aEndOffset,
nsAString& aText);
void TextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset, int32_t* aEndOffset,
nsAString& aText);
void TextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset, int32_t* aEndOffset,
nsAString& aText);
/**
* Return text attributes for the given text range.
*/
already_AddRefed<nsIPersistentProperties>
TextAttributes(bool aIncludeDefAttrs, int32_t aOffset,
int32_t* aStartOffset, int32_t* aEndOffset);
/**
* Return text attributes applied to the accessible.
*/
already_AddRefed<nsIPersistentProperties> DefaultTextAttributes();
/**
* Return text offset of the given child accessible within hypertext
* accessible.
@ -247,14 +269,34 @@ public:
}
/**
* Return the bounds of the text between given start and end offset.
* Return true if the given offset/range is valid.
*/
nsIntRect GetTextBounds(int32_t aStartOffset, int32_t aEndOffset)
{
nsIntRect bounds;
GetPosAndText(aStartOffset, aEndOffset, nullptr, nullptr, &bounds);
return bounds;
}
bool IsValidOffset(int32_t aOffset);
bool IsValidRange(int32_t aStartOffset, int32_t aEndOffset);
/**
* Return an offset at the given point.
*/
int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
/**
* Return a rect of the given text range relative given coordinate system.
*/
nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
/**
* Return a rect for character at given offset relative given coordinate
* system.
*/
nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType)
{ return TextBounds(aOffset, aOffset + 1, aCoordType); }
/**
* Get/set caret offset, if no caret then -1.
*/
int32_t CaretOffset() const;
void SetCaretOffset(int32_t aOffset) { SetSelectionRange(aOffset, aOffset); }
/**
* Provide the line number for the caret.
@ -271,9 +313,60 @@ public:
*/
nsIntRect GetCaretRect(nsIWidget** aWidget);
/**
* Return selected regions count within the accessible.
*/
int32_t SelectionCount();
/**
* Return the start and end offset of the specified selection.
*/
bool SelectionBoundsAt(int32_t aSelectionNum,
int32_t* aStartOffset, int32_t* aEndOffset);
/*
* Changes the start and end offset of the specified selection.
* @return true if succeeded
*/
bool SetSelectionBoundsAt(int32_t aSelectionNum,
int32_t aStartOffset, int32_t aEndOffset);
/**
* Adds a selection bounded by the specified offsets.
* @return true if succeeded
*/
bool AddToSelection(int32_t aStartOffset, int32_t aEndOffset);
/*
* Removes the specified selection.
* @return true if succeeded
*/
bool RemoveFromSelection(int32_t aSelectionNum);
/**
* Scroll the given text range into view.
*/
void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aScrollType);
/**
* Scroll the given text range to the given point.
*/
void ScrollSubstringToPoint(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aCoordinateType,
int32_t aX, int32_t aY);
//////////////////////////////////////////////////////////////////////////////
// EditableTextAccessible
void ReplaceText(const nsAString& aText);
void InsertText(const nsAString& aText, int32_t aPosition);
void CopyText(int32_t aStartPos, int32_t aEndPos);
void CutText(int32_t aStartPos, int32_t aEndPos);
void DeleteText(int32_t aStartPos, int32_t aEndPos);
void PasteText(int32_t aPosition);
/**
* Return the editor associated with the accessible.
*/
@ -289,39 +382,12 @@ protected:
/**
* Transform magic offset into text offset.
*/
int32_t ConvertMagicOffset(int32_t aOffset)
{
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
return CharacterCount();
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
int32_t caretOffset = -1;
GetCaretOffset(&caretOffset);
return caretOffset;
}
return aOffset;
}
int32_t ConvertMagicOffset(int32_t aOffset);
/**
* Adjust an offset the caret stays at to get a text by line boundary.
*/
int32_t AdjustCaretOffset(int32_t aOffset)
{
// It is the same character offset when the caret is visually at the very
// end of a line or the start of a new line (soft line break). Getting text
// at the line should provide the line with the visual caret, otherwise
// screen readers will announce the wrong line as the user presses up or
// down arrow and land at the end of a line.
if (aOffset > 0) {
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
if (frameSelection &&
frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
return aOffset - 1;
}
}
return aOffset;
}
int32_t AdjustCaretOffset(int32_t aOffset) const;
/**
* Return true if the given offset points to terminal empty line if any.
@ -427,9 +493,10 @@ protected:
// Selection helpers
/**
* Return frame selection object for the accessible.
* Return frame/DOM selection object for the accessible.
*/
virtual already_AddRefed<nsFrameSelection> FrameSelection();
virtual already_AddRefed<nsFrameSelection> FrameSelection() const;
Selection* DOMSelection() const;
/**
* Return selection ranges within the accessible subtree.
@ -443,7 +510,7 @@ protected:
Accessible* aAccessible,
mozilla::a11y::DOMPoint* aPoint);
/**
* Return hyper text offset for the specified bound of the given DOM range.
* If the bound is outside of the hyper text then offset value is either
@ -466,7 +533,7 @@ protected:
* Set 'misspelled' text attribute and return range offsets where the
* attibute is stretched. If the text is not misspelled at the given offset
* then we expose only range offsets where text is not misspelled. The method
* is used by GetTextAttributes() method.
* is used by TextAttributes() method.
*
* @param aIncludeDefAttrs [in] points whether text attributes having default
* values of attributes should be included

View File

@ -12,7 +12,7 @@ EXPORTS.mozilla.a11y += [
'HyperTextAccessible.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'Accessible.cpp',
'ApplicationAccessible.cpp',
'ARIAGridAccessible.cpp',

View File

@ -6,7 +6,7 @@
MODULE = 'accessibility'
SOURCES += [
UNIFIED_SOURCES += [
'HTMLCanvasAccessible.cpp',
'HTMLElementAccessibles.cpp',
'HTMLFormControlAccessible.cpp',

View File

@ -17,7 +17,7 @@ EXPORTS.mozilla.a11y += [
LIBRARY_NAME = 'accessibility_toolkit_s'
SOURCES += [
UNIFIED_SOURCES += [
'AccessibleWrap.mm',
'DocAccessibleWrap.mm',
'MacUtils.mm',

View File

@ -4,9 +4,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Accessible-inl.h"
#include "AccessibleWrap.h"
#include "HyperTextAccessible-inl.h"
#include "TextLeafAccessible.h"
#include "nsIAccessibleTypes.h"
#include "nsCocoaUtils.h"
#include "nsObjCExceptions.h"
@ -213,10 +212,10 @@ ToNSString(id aValue)
#endif
return nil;
}
int32_t start = range.location;
int32_t end = start + range.length;
nsIntRect bounds = mGeckoTextAccessible->GetTextBounds(start, end);
nsIntRect bounds = mGeckoTextAccessible->TextBounds(start, end);
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
}
@ -263,21 +262,13 @@ ToNSString(id aValue)
if (!stringValue)
return;
int32_t start = 0;
int32_t end = 0;
nsresult rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end);
NS_ENSURE_SUCCESS(rv,);
rv = mGeckoTextAccessible->DeleteText(start, end - start);
NS_ENSURE_SUCCESS(rv,);
int32_t start = 0, end = 0;
mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
mGeckoTextAccessible->DeleteText(start, end - start);
nsString text;
nsCocoaUtils::GetStringForNSString(stringValue, text);
rv = mGeckoTextAccessible->InsertText(text, start);
NS_ENSURE_SUCCESS(rv,);
return;
mGeckoTextAccessible->InsertText(text, start);
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
@ -285,10 +276,8 @@ ToNSString(id aValue)
if (!ToNSRange(value, &range))
return;
nsresult rv = mGeckoTextAccessible->SetSelectionBounds(0, range.location,
range.location + range.length);
NS_ENSURE_SUCCESS(rv,);
mGeckoTextAccessible->SetSelectionBoundsAt(0, range.location,
range.location + range.length);
return;
}
@ -374,10 +363,9 @@ ToNSString(id aValue)
return @"";
nsAutoString text;
nsresult rv = mGeckoTextAccessible->
GetText(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
NS_ENSURE_SUCCESS(rv, @"");
mGeckoTextAccessible->TextSubstring(0,
nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT,
text);
return nsCocoaUtils::ToNSString(text);
}
@ -398,11 +386,8 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if (mGeckoTextAccessible) {
int32_t start, end;
start = end = 0;
nsresult rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end);
NS_ENSURE_SUCCESS(rv, 0);
int32_t start = 0, end = 0;
mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
return (end - start);
}
return 0;
@ -415,12 +400,11 @@ ToNSString(id aValue)
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (mGeckoTextAccessible) {
int32_t start, end;
start = end = 0;
mGeckoTextAccessible->GetSelectionBounds(0, &start, &end);
int32_t start = 0, end = 0;
mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
if (start != end) {
nsAutoString selText;
mGeckoTextAccessible->GetText(start, end, selText);
mGeckoTextAccessible->TextSubstring(start, end, selText);
return nsCocoaUtils::ToNSString(selText);
}
}
@ -436,21 +420,14 @@ ToNSString(id aValue)
if (mGeckoTextAccessible) {
int32_t start = 0;
int32_t end = 0;
int32_t count = 0;
nsresult rv = mGeckoTextAccessible->GetSelectionCount(&count);
NS_ENSURE_SUCCESS(rv, nil);
int32_t count = mGeckoTextAccessible->SelectionCount();
if (count) {
rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end);
NS_ENSURE_SUCCESS(rv, nil);
mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
rv = mGeckoTextAccessible->GetCaretOffset(&start);
NS_ENSURE_SUCCESS(rv, nil);
start = mGeckoTextAccessible->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
return [NSValue valueWithRange:NSMakeRange(0, 0)];
@ -488,8 +465,8 @@ ToNSString(id aValue)
NS_PRECONDITION(mGeckoTextAccessible && range, "no Gecko text accessible or range");
nsAutoString text;
mGeckoTextAccessible->GetText(range->location,
range->location + range->length, text);
mGeckoTextAccessible->TextSubstring(range->location,
range->location + range->length, text);
return nsCocoaUtils::ToNSString(text);
}

View File

@ -8,6 +8,7 @@
#include "ia2AccessibleEditableText.h"
#include "AccessibleEditableText_i.c"
#include "HyperTextAccessible-inl.h"
#include "HyperTextAccessibleWrap.h"
#include "nsCOMPtr.h"
@ -26,8 +27,11 @@ ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->CopyText(aStartOffset, aEndOffset);
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
return E_INVALIDARG;
textAcc->CopyText(aStartOffset, aEndOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -41,8 +45,11 @@ ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
return E_INVALIDARG;
textAcc->DeleteText(aStartOffset, aEndOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -56,11 +63,14 @@ ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (!textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
uint32_t length = ::SysStringLen(*aText);
nsAutoString text(*aText, length);
nsresult rv = textAcc->InsertText(text, aOffset);
return GetHRESULT(rv);
textAcc->InsertText(text, aOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -74,8 +84,11 @@ ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->CutText(aStartOffset, aEndOffset);
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
return E_INVALIDARG;
textAcc->CutText(aStartOffset, aEndOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -89,8 +102,11 @@ ia2AccessibleEditableText::pasteText(long aOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->PasteText(aOffset);
return GetHRESULT(rv);
if (!textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
textAcc->PasteText(aOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -105,15 +121,16 @@ ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
return E_INVALIDARG;
textAcc->DeleteText(aStartOffset, aEndOffset);
uint32_t length = ::SysStringLen(*aText);
nsAutoString text(*aText, length);
textAcc->InsertText(text, aStartOffset);
rv = textAcc->InsertText(text, aStartOffset);
return GetHRESULT(rv);
return S_OK;
A11Y_TRYBLOCK_END
}

View File

@ -30,7 +30,7 @@ ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount)
if (hyperText->IsDefunct())
return CO_E_OBJNOTCONNECTED;
*aHyperlinkCount = hyperText->GetLinkCount();
*aHyperlinkCount = hyperText->LinkCount();
return S_OK;
A11Y_TRYBLOCK_END
@ -51,7 +51,7 @@ ia2AccessibleHypertext::get_hyperlink(long aLinkIndex,
if (hyperText->IsDefunct())
return CO_E_OBJNOTCONNECTED;
Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
Accessible* hyperLink = hyperText->LinkAt(aLinkIndex);
if (!hyperLink)
return E_FAIL;
@ -77,7 +77,7 @@ ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkInde
if (hyperAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
*aHyperlinkIndex = hyperAcc->GetLinkIndexAtOffset(aCharIndex);
*aHyperlinkIndex = hyperAcc->LinkIndexAtOffset(aCharIndex);
return S_OK;
A11Y_TRYBLOCK_END

View File

@ -11,9 +11,7 @@
#include "AccessibleText_i.c"
#include "HyperTextAccessibleWrap.h"
#include "nsIPersistentProperties2.h"
#include "nsIAccessibleTypes.h"
#include "HyperTextAccessible-inl.h"
using namespace mozilla::a11y;
@ -28,8 +26,8 @@ ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->AddSelection(aStartOffset, aEndOffset);
return GetHRESULT(rv);
return textAcc->AddToSelection(aStartOffset, aEndOffset) ?
S_OK : E_INVALIDARG;
A11Y_TRYBLOCK_END
}
@ -52,13 +50,9 @@ ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
return CO_E_OBJNOTCONNECTED;
int32_t startOffset = 0, endOffset = 0;
nsCOMPtr<nsIPersistentProperties> attributes;
nsresult rv = textAcc->GetTextAttributes(true, aOffset,
&startOffset, &endOffset,
getter_AddRefs(attributes));
if (NS_FAILED(rv))
return GetHRESULT(rv);
nsCOMPtr<nsIPersistentProperties> attributes =
textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset);
HRESULT hr = AccessibleWrap::ConvertToIA2Attributes(attributes,
aTextAttributes);
if (FAILED(hr))
@ -86,13 +80,8 @@ ia2AccessibleText::get_caretOffset(long *aOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
int32_t offset = 0;
nsresult rv = textAcc->GetCaretOffset(&offset);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aOffset = offset;
return offset != -1 ? S_OK : S_FALSE;
*aOffset = textAcc->CaretOffset();
return *aOffset != -1 ? S_OK : S_FALSE;
A11Y_TRYBLOCK_END
}
@ -100,18 +89,14 @@ ia2AccessibleText::get_caretOffset(long *aOffset)
STDMETHODIMP
ia2AccessibleText::get_characterExtents(long aOffset,
enum IA2CoordinateType aCoordType,
long *aX, long *aY,
long *aWidth, long *aHeight)
long* aX, long* aY,
long* aWidth, long* aHeight)
{
A11Y_TRYBLOCK_BEGIN
if (!aX || !aY || !aWidth || !aHeight)
return E_INVALIDARG;
*aX = 0;
*aY = 0;
*aWidth = 0;
*aHeight = 0;
*aX = *aY = *aWidth = *aHeight = 0;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
@ -121,41 +106,31 @@ ia2AccessibleText::get_characterExtents(long aOffset,
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
int32_t x = 0, y =0, width = 0, height = 0;
nsresult rv = textAcc->GetCharacterExtents (aOffset, &x, &y, &width, &height,
geckoCoordType);
if (NS_FAILED(rv))
return GetHRESULT(rv);
nsIntRect rect = textAcc->CharBounds(aOffset, geckoCoordType);
*aX = x;
*aY = y;
*aWidth = width;
*aHeight = height;
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;
*aHeight = rect.height;
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
ia2AccessibleText::get_nSelections(long *aNSelections)
ia2AccessibleText::get_nSelections(long* aNSelections)
{
A11Y_TRYBLOCK_BEGIN
if (!aNSelections)
return E_INVALIDARG;
*aNSelections = 0;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
int32_t selCount = 0;
nsresult rv = textAcc->GetSelectionCount(&selCount);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aNSelections = selCount;
*aNSelections = textAcc->SelectionCount();
return S_OK;
A11Y_TRYBLOCK_END
@ -164,13 +139,12 @@ ia2AccessibleText::get_nSelections(long *aNSelections)
STDMETHODIMP
ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
enum IA2CoordinateType aCoordType,
long *aOffset)
long* aOffset)
{
A11Y_TRYBLOCK_BEGIN
if (!aOffset)
return E_INVALIDARG;
*aOffset = 0;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@ -181,38 +155,29 @@ ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
int32_t offset = 0;
nsresult rv = textAcc->GetOffsetAtPoint(aX, aY, geckoCoordType, &offset);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aOffset = offset;
return S_OK;
*aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType);
return *aOffset == -1 ? S_FALSE : S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
long *aEndOffset)
ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset,
long* aEndOffset)
{
A11Y_TRYBLOCK_BEGIN
if (!aStartOffset || !aEndOffset)
return E_INVALIDARG;
*aStartOffset = 0;
*aEndOffset = 0;
*aStartOffset = *aEndOffset = 0;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
int32_t startOffset = 0, endOffset = 0;
nsresult rv = textAcc->GetSelectionBounds(aSelectionIndex,
&startOffset, &endOffset);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset))
return E_INVALIDARG;
*aStartOffset = startOffset;
*aEndOffset = endOffset;
@ -222,7 +187,7 @@ ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
}
STDMETHODIMP
ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText)
{
A11Y_TRYBLOCK_BEGIN
@ -235,11 +200,11 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsAutoString text;
nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text);
if (NS_FAILED(rv))
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
return E_INVALIDARG;
nsAutoString text;
textAcc->TextSubstring(aStartOffset, aEndOffset, text);
if (text.IsEmpty())
return S_FALSE;
@ -252,40 +217,38 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
STDMETHODIMP
ia2AccessibleText::get_textBeforeOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
long* aStartOffset, long* aEndOffset,
BSTR* aText)
{
A11Y_TRYBLOCK_BEGIN
if (!aStartOffset || !aEndOffset || !aText)
return E_INVALIDARG;
*aStartOffset = 0;
*aEndOffset = 0;
*aStartOffset = *aEndOffset = 0;
*aText = nullptr;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = NS_OK;
if (textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
nsAutoString text;
int32_t startOffset = 0, endOffset = 0;
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
textAcc->TextSubstring(startOffset, endOffset, text);
} else {
AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
if (boundaryType == -1)
return S_FALSE;
rv = textAcc->GetTextBeforeOffset(aOffset, boundaryType,
&startOffset, &endOffset, text);
}
if (NS_FAILED(rv))
return GetHRESULT(rv);
textAcc->TextBeforeOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
}
*aStartOffset = startOffset;
*aEndOffset = endOffset;
@ -302,8 +265,8 @@ ia2AccessibleText::get_textBeforeOffset(long aOffset,
STDMETHODIMP
ia2AccessibleText::get_textAfterOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
long* aStartOffset, long* aEndOffset,
BSTR* aText)
{
A11Y_TRYBLOCK_BEGIN
@ -318,25 +281,23 @@ ia2AccessibleText::get_textAfterOffset(long aOffset,
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = NS_OK;
if (textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
nsAutoString text;
int32_t startOffset = 0, endOffset = 0;
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
textAcc->TextSubstring(startOffset, endOffset, text);
} else {
AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
if (boundaryType == -1)
return S_FALSE;
rv = textAcc->GetTextAfterOffset(aOffset, boundaryType,
&startOffset, &endOffset, text);
textAcc->TextAfterOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
}
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
@ -352,41 +313,37 @@ ia2AccessibleText::get_textAfterOffset(long aOffset,
STDMETHODIMP
ia2AccessibleText::get_textAtOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
long* aStartOffset, long* aEndOffset,
BSTR* aText)
{
A11Y_TRYBLOCK_BEGIN
if (!aStartOffset || !aEndOffset || !aText)
return E_INVALIDARG;
*aStartOffset = 0;
*aEndOffset = 0;
*aStartOffset = *aEndOffset = 0;
*aText = nullptr;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = NS_OK;
if (textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
nsAutoString text;
int32_t startOffset = 0, endOffset = 0;
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
textAcc->TextSubstring(startOffset, endOffset, text);
} else {
AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
if (boundaryType == -1)
return S_FALSE;
rv = textAcc->GetTextAtOffset(aOffset, boundaryType,
&startOffset, &endOffset, text);
textAcc->TextAtOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
}
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
@ -408,8 +365,8 @@ ia2AccessibleText::removeSelection(long aSelectionIndex)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->RemoveSelection(aSelectionIndex);
return GetHRESULT(rv);
return textAcc->RemoveFromSelection(aSelectionIndex) ?
S_OK : E_INVALIDARG;
A11Y_TRYBLOCK_END
}
@ -423,8 +380,11 @@ ia2AccessibleText::setCaretOffset(long aOffset)
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->SetCaretOffset(aOffset);
return GetHRESULT(rv);
if (!textAcc->IsValidOffset(aOffset))
return E_INVALIDARG;
textAcc->SetCaretOffset(aOffset);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -439,21 +399,19 @@ ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->SetSelectionBounds(aSelectionIndex,
aStartOffset, aEndOffset);
return GetHRESULT(rv);
return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ?
S_OK : E_INVALIDARG;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
ia2AccessibleText::get_nCharacters(long *aNCharacters)
ia2AccessibleText::get_nCharacters(long* aNCharacters)
{
A11Y_TRYBLOCK_BEGIN
if (!aNCharacters)
return E_INVALIDARG;
*aNCharacters = 0;
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@ -476,8 +434,11 @@ ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
return GetHRESULT(rv);
if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
return E_INVALIDARG;
textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
return S_OK;
A11Y_TRYBLOCK_END
}
@ -493,13 +454,16 @@ ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
return E_INVALIDARG;
uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
nsresult rv = textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
geckoCoordType, aX, aY);
return GetHRESULT(rv);
textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
geckoCoordType, aX, aY);
return S_OK;
A11Y_TRYBLOCK_END
}

View File

@ -9,7 +9,6 @@
#define mozilla_a11y_IUnknownImpl_h_
#include <windows.h>
#undef CreateEvent // thank you windows you're such a helper
#include "nsError.h"
// Avoid warning C4509 like "nonstandard extension used:

View File

@ -7,11 +7,13 @@
MODULE = 'accessibility'
EXPORTS += [
'xpcAccessibleHyperText.h',
'xpcAccessibleSelectable.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'nsAccessibleRelation.cpp',
'xpcAccessibleHyperText.cpp',
'xpcAccessibleSelectable.cpp',
'xpcAccessibleTable.cpp',
'xpcAccessibleTableCell.cpp',

View File

@ -0,0 +1,507 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "xpcAccessibleHyperText.h"
#include "HyperTextAccessible-inl.h"
#include "nsIPersistentProperties2.h"
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// nsISupports
nsresult
xpcAccessibleHyperText::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
*aInstancePtr = nullptr;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (!text->IsTextRole())
return NS_ERROR_NO_INTERFACE;
if (aIID.Equals(NS_GET_IID(nsIAccessibleText)))
*aInstancePtr = static_cast<nsIAccessibleText*>(text);
else if (aIID.Equals(NS_GET_IID(nsIAccessibleEditableText)))
*aInstancePtr = static_cast<nsIAccessibleEditableText*>(text);
else if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperText)))
*aInstancePtr = static_cast<nsIAccessibleHyperText*>(text);
else
return NS_ERROR_NO_INTERFACE;
NS_ADDREF(text);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleText
NS_IMETHODIMP
xpcAccessibleHyperText::GetCharacterCount(int32_t* aCharacterCount)
{
NS_ENSURE_ARG_POINTER(aCharacterCount);
*aCharacterCount = 0;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aCharacterCount = text->CharacterCount();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetText(int32_t aStartOffset, int32_t aEndOffset,
nsAString& aText)
{
aText.Truncate();
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->TextSubstring(aStartOffset, aEndOffset, aText);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetTextBeforeOffset(int32_t aOffset,
AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset,
int32_t* aEndOffset,
nsAString& aText)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
*aStartOffset = *aEndOffset = 0;
aText.Truncate();
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset,
AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset,
int32_t* aEndOffset, nsAString& aText)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
*aStartOffset = *aEndOffset = 0;
aText.Truncate();
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset,
AccessibleTextBoundary aBoundaryType,
int32_t* aStartOffset,
int32_t* aEndOffset, nsAString& aText)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
*aStartOffset = *aEndOffset = 0;
aText.Truncate();
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset,
PRUnichar* aCharacter)
{
NS_ENSURE_ARG_POINTER(aCharacter);
*aCharacter = L'\0';
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsAutoString character;
if (text->GetCharAt(aOffset, eGetAt, character)) {
*aCharacter = character.First();
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetTextAttributes(bool aIncludeDefAttrs,
int32_t aOffset,
int32_t* aStartOffset,
int32_t* aEndOffset,
nsIPersistentProperties** aAttributes)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
NS_ENSURE_ARG_POINTER(aAttributes);
*aStartOffset = *aEndOffset = 0;
*aAttributes = nullptr;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attrs =
text->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset);
attrs.swap(*aAttributes);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetDefaultTextAttributes(nsIPersistentProperties** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nullptr;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attrs = text->DefaultTextAttributes();
attrs.swap(*aAttributes);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetCharacterExtents(int32_t aOffset,
int32_t* aX, int32_t* aY,
int32_t* aWidth, int32_t* aHeight,
uint32_t aCoordType)
{
NS_ENSURE_ARG_POINTER(aX);
NS_ENSURE_ARG_POINTER(aY);
NS_ENSURE_ARG_POINTER(aWidth);
NS_ENSURE_ARG_POINTER(aHeight);
*aX = *aY = *aWidth = *aHeight;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsIntRect rect = text->CharBounds(aOffset, aCoordType);
*aX = rect.x; *aY = rect.y;
*aWidth = rect.width; *aHeight = rect.height;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetRangeExtents(int32_t aStartOffset, int32_t aEndOffset,
int32_t* aX, int32_t* aY,
int32_t* aWidth, int32_t* aHeight,
uint32_t aCoordType)
{
NS_ENSURE_ARG_POINTER(aX);
NS_ENSURE_ARG_POINTER(aY);
NS_ENSURE_ARG_POINTER(aWidth);
NS_ENSURE_ARG_POINTER(aHeight);
*aX = *aY = *aWidth = *aHeight = 0;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, aCoordType);
*aX = rect.x; *aY = rect.y;
*aWidth = rect.width; *aHeight = rect.height;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY,
uint32_t aCoordType, int32_t* aOffset)
{
NS_ENSURE_ARG_POINTER(aOffset);
*aOffset = -1;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aOffset = text->OffsetAtPoint(aX, aY, aCoordType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetScriptableCaretOffset(int32_t* aCaretOffset)
{
NS_ENSURE_ARG_POINTER(aCaretOffset);
*aCaretOffset = -1;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aCaretOffset = text->CaretOffset();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::SetScriptableCaretOffset(int32_t aCaretOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->SetCaretOffset(aCaretOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount)
{
NS_ENSURE_ARG_POINTER(aSelectionCount);
*aSelectionCount = 0;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aSelectionCount = text->SelectionCount();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetSelectionBounds(int32_t aSelectionNum,
int32_t* aStartOffset,
int32_t* aEndOffset)
{
NS_ENSURE_ARG_POINTER(aStartOffset);
NS_ENSURE_ARG_POINTER(aEndOffset);
*aStartOffset = *aEndOffset = 0;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
if (aSelectionNum < 0 || aSelectionNum >= text->SelectionCount())
return NS_ERROR_INVALID_ARG;
text->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::SetSelectionBounds(int32_t aSelectionNum,
int32_t aStartOffset,
int32_t aEndOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
if (aSelectionNum < 0 ||
!text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset))
return NS_ERROR_INVALID_ARG;
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->AddToSelection(aStartOffset, aEndOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->RemoveFromSelection(aSelectionNum);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableScrollSubstringTo(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aScrollType)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableScrollSubstringToPoint(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aCoordinateType,
int32_t aX, int32_t aY)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType, aX, aY);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleEditableText
NS_IMETHODIMP
xpcAccessibleHyperText::SetTextContents(const nsAString& aText)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->ReplaceText(aText);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableInsertText(const nsAString& aText,
int32_t aOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->InsertText(aText, aOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableCopyText(int32_t aStartOffset,
int32_t aEndOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->CopyText(aStartOffset, aEndOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableCutText(int32_t aStartOffset,
int32_t aEndOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->CutText(aStartOffset, aEndOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptableDeleteText(int32_t aStartOffset,
int32_t aEndOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->DeleteText(aStartOffset, aEndOffset);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::ScriptablePasteText(int32_t aOffset)
{
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
text->PasteText(aOffset);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleHyperText
NS_IMETHODIMP
xpcAccessibleHyperText::GetLinkCount(int32_t* aLinkCount)
{
NS_ENSURE_ARG_POINTER(aLinkCount);
*aLinkCount = 0;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aLinkCount = text->LinkCount();
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetLinkAt(int32_t aIndex, nsIAccessibleHyperLink** aLink)
{
NS_ENSURE_ARG_POINTER(aLink);
*aLink = nullptr;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessibleHyperLink> link = text->LinkAt(aIndex);
link.forget(aLink);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetLinkIndex(nsIAccessibleHyperLink* aLink,
int32_t* aIndex)
{
NS_ENSURE_ARG_POINTER(aLink);
NS_ENSURE_ARG_POINTER(aIndex);
*aIndex = -1;
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
nsRefPtr<Accessible> link(do_QueryObject(aLink));
*aIndex = text->LinkIndexOf(link);
return NS_OK;
}
NS_IMETHODIMP
xpcAccessibleHyperText::GetLinkIndexAtOffset(int32_t aOffset,
int32_t* aLinkIndex)
{
NS_ENSURE_ARG_POINTER(aLinkIndex);
*aLinkIndex = -1; // API says this magic value means 'not found'
HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
if (text->IsDefunct())
return NS_ERROR_FAILURE;
*aLinkIndex = text->LinkIndexAtOffset(aOffset);
return NS_OK;
}

View File

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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_a11y_xpcAccessibleHyperText_h_
#define mozilla_a11y_xpcAccessibleHyperText_h_
#include "nsIAccessibleText.h"
#include "nsIAccessibleHyperText.h"
#include "nsIAccessibleEditableText.h"
namespace mozilla {
namespace a11y {
class xpcAccessibleHyperText : public nsIAccessibleText,
public nsIAccessibleEditableText,
public nsIAccessibleHyperText
{
public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_DECL_NSIACCESSIBLETEXT
NS_DECL_NSIACCESSIBLEHYPERTEXT
NS_DECL_NSIACCESSIBLEEDITABLETEXT
private:
xpcAccessibleHyperText() { }
friend class HyperTextAccessible;
xpcAccessibleHyperText(const xpcAccessibleHyperText&) MOZ_DELETE;
xpcAccessibleHyperText& operator =(const xpcAccessibleHyperText&) MOZ_DELETE;
};
} // namespace a11y
} // namespace mozilla
#endif // mozilla_a11y_xpcAccessibleHyperText_h_

View File

@ -811,7 +811,7 @@ XULTextFieldAccessible::CacheChildren()
// XULTextFieldAccessible: HyperTextAccessible protected
already_AddRefed<nsFrameSelection>
XULTextFieldAccessible::FrameSelection()
XULTextFieldAccessible::FrameSelection() const
{
nsCOMPtr<nsIContent> inputContent(GetInputField());
NS_ASSERTION(inputContent, "No input content");

View File

@ -250,7 +250,7 @@ protected:
virtual void CacheChildren();
// HyperTextAccessible
virtual already_AddRefed<nsFrameSelection> FrameSelection();
virtual already_AddRefed<nsFrameSelection> FrameSelection() const;
// nsXULTextFieldAccessible
already_AddRefed<nsIContent> GetInputField() const;

View File

@ -6,7 +6,7 @@
MODULE = 'accessibility'
SOURCES += [
UNIFIED_SOURCES += [
'XULAlertAccessible.cpp',
'XULColorPickerAccessible.cpp',
'XULComboboxAccessible.cpp',

View File

@ -415,7 +415,7 @@ function testTextSetSelection(aID, aStartOffset, aEndOffset,
var text = acc.getText(0, -1);
acc.setSelectionBounds(aSelectionIndex, aStartOffset, aEndOffset);
is(acc.selectionCount, aSelectionsCount,
text + ": failed to set selection at index '" +
aSelectionIndex + "': selectionCount after");

View File

@ -659,6 +659,7 @@ let gHistorySwipeAnimation = {
*/
stopAnimation: function HSA_stopAnimation() {
gHistorySwipeAnimation._removeBoxes();
this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
},
/**
@ -724,23 +725,27 @@ let gHistorySwipeAnimation = {
* An event to process.
*/
handleEvent: function HSA_handleEvent(aEvent) {
let browser = gBrowser.selectedBrowser;
switch (aEvent.type) {
case "TabClose":
let browser = gBrowser.getBrowserForTab(aEvent.target);
this._removeTrackedSnapshot(-1, browser);
let browserForTab = gBrowser.getBrowserForTab(aEvent.target);
this._removeTrackedSnapshot(-1, browserForTab);
break;
case "DOMModalDialogClosed":
this.stopAnimation();
break;
case "pageshow":
if (aEvent.target == browser.contentDocument) {
this.stopAnimation();
}
break;
case "popstate":
if (aEvent.target != gBrowser.selectedBrowser.contentDocument)
break;
this.stopAnimation();
this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
if (aEvent.target == browser.contentDocument.defaultView) {
this.stopAnimation();
}
break;
case "pagehide":
if (aEvent.target == gBrowser.selectedBrowser.contentDocument) {
if (aEvent.target == browser.contentDocument) {
// Take and compress a snapshot of a page whenever it's about to be
// navigated away from. We already have a snapshot of the page if an
// animation is running, so we're left with compressing it.

View File

@ -88,8 +88,9 @@ ifneq (,$(findstring mingw,$(CONFIG_GUESS)))
# check for CRLF line endings
ifneq (0,$(shell $(PERL) -e 'binmode(STDIN); while (<STDIN>) { if (/\r/) { print "1"; exit } } print "0"' < $(TOPSRCDIR)/client.mk))
$(error This source tree appears to have Windows-style line endings. To \
convert it to Unix-style line endings, run \
"python mozilla/build/win32/mozilla-dos2unix.py")
convert it to Unix-style line endings, check \
"https://developer.mozilla.org/en-US/docs/Developer_Guide/Mozilla_build_FAQ\#Win32-specific_questions" \
for a workaround of this issue.)
endif
endif

View File

@ -8733,13 +8733,6 @@ if test "$MOZ_X11"; then
fi # MOZ_X11
dnl Check for headers, etc. needed by WebGL.
if test "$MOZ_GL_DEFAULT_PROVIDER" = "GLX"; then
MOZ_CHECK_HEADER(GL/glx.h)
if test "$ac_cv_header_GL_glx_h" != "yes"; then
AC_MSG_ERROR([Can't find header GL/glx.h for WebGL (install mesa-common-dev (Ubuntu), mesa-libGL-devel (Fedora), or Mesa-devel (openSUSE))])
fi
fi # MOZ_GL_DEFAULT_PROVIDER=GLX
fi # COMPILE_ENVIRONMENT
dnl Set various defines and substitutions

View File

@ -1848,7 +1848,6 @@ GK_ATOM(svgFilterFrame, "SVGFilterFrame")
GK_ATOM(svgForeignObjectFrame, "SVGForeignObjectFrame")
GK_ATOM(svgGenericContainerFrame, "SVGGenericContainerFrame")
GK_ATOM(svgGFrame, "SVGGFrame")
GK_ATOM(svgGlyphFrame, "SVGGlyphFrame")
GK_ATOM(svgGradientFrame, "SVGGradientFrame")
GK_ATOM(svgImageFrame, "SVGImageFrame")
GK_ATOM(svgInnerSVGFrame, "SVGInnerSVGFrame")
@ -1863,10 +1862,7 @@ GK_ATOM(svgPatternFrame, "SVGPatternFrame")
GK_ATOM(svgRadialGradientFrame, "SVGRadialGradientFrame")
GK_ATOM(svgStopFrame, "SVGStopFrame")
GK_ATOM(svgSwitchFrame, "SVGSwitchFrame")
GK_ATOM(svgTextFrame, "SVGTextFrame")
GK_ATOM(svgTextFrame2, "SVGTextFrame2")
GK_ATOM(svgTextPathFrame, "SVGTextPathFrame")
GK_ATOM(svgTSpanFrame, "SVGTSpanFrame")
GK_ATOM(svgUseFrame, "SVGUseFrame")
GK_ATOM(svgViewFrame, "SVGViewFrame")
GK_ATOM(HTMLVideoFrame, "VideoFrame")

View File

@ -3107,6 +3107,15 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
imgSize = res.mSize;
// Scale sw/sh based on aspect ratio
if (image.IsHTMLVideoElement()) {
HTMLVideoElement* video = &image.GetAsHTMLVideoElement();
int32_t displayWidth = video->VideoWidth();
int32_t displayHeight = video->VideoHeight();
sw *= (double)imgSize.width / (double)displayWidth;
sh *= (double)imgSize.height / (double)displayHeight;
}
if (mCanvasElement) {
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
res.mPrincipal, res.mIsWriteOnly,

View File

@ -15,7 +15,7 @@ EXPORTS.mozilla.dom += [
'TextMetrics.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'CanvasImageCache.cpp',
'CanvasRenderingContext2D.cpp',
'CanvasUtils.cpp',
@ -26,7 +26,7 @@ SOURCES += [
]
if CONFIG['MOZ_WEBGL']:
SOURCES += [
UNIFIED_SOURCES += [
'WebGL1Context.cpp',
'WebGL2Context.cpp',
'WebGLActiveInfo.cpp',
@ -77,7 +77,7 @@ if CONFIG['MOZ_WEBGL']:
'/js/xpconnect/wrappers',
]
else:
SOURCES += [
UNIFIED_SOURCES += [
'WebGLContextNotSupported.cpp',
]

View File

@ -54,6 +54,9 @@ nsDOMEvent::ConstructorInit(mozilla::dom::EventTarget* aOwner,
SetIsDOMBinding();
SetOwner(aOwner);
mIsMainThreadEvent = mOwner || NS_IsMainThread();
if (mIsMainThreadEvent) {
nsJSContext::LikelyShortLivingObjectCreated();
}
mPrivateDataDuplicated = false;
@ -92,7 +95,6 @@ nsDOMEvent::ConstructorInit(mozilla::dom::EventTarget* aOwner,
}
InitPresContextData(aPresContext);
nsJSContext::LikelyShortLivingObjectCreated();
}
void

Binary file not shown.

View File

@ -423,6 +423,13 @@ var gChainingTests = [
{ name:"bogus.duh", type:"bogus/duh" }
];
// Videos with an aspect ratio. Used for testing that displaying frames
// on a canvas works correctly in the case of non-standard aspect ratios.
// See bug 874897 for an example.
var gAspectRatioTests = [
{ name:"VID_0001.ogg", type:"video/ogg", duration:19.966 }
];
// These are files with non-trivial tag sets.
// Used by test_metadata.html.
var gMetadataTests = [

View File

@ -165,6 +165,7 @@ support-files =
variable-samplerate.ogg
variable-samplerate.opus
vbr.mp3
VID_0001.ogg
video-overhang.ogg
wave_metadata.wav
wave_metadata_bad_len.wav
@ -185,6 +186,7 @@ support-files =
[test_bug495300.html]
[test_bug654550.html]
[test_bug686942.html]
[test_bug874897.html]
[test_bug883173.html]
[test_bug895305.html]
[test_bug895091.html]

View File

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=874897
-->
<head>
<title>Test for Bug 874897</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
function loadeddata(e) {
var v = e.target;
ok(v.readyState >= v.HAVE_CURRENT_DATA,
"readyState must be >= HAVE_CURRENT_DATA for " + v._name);
var canvas = document.createElement("canvas");
canvas.width = 210;
canvas.height = 120;
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
try {
ctx.drawImage(v, 0, 0, v.videoWidth, v.videoHeight, 0, 0, canvas.width, canvas.height);
ok(true, "Shouldn't throw exception while drawing to canvas from video for " + v._name);
} catch (ex) {
ok(false, "Shouldn't throw exception while drawing to canvas from video for " + v._name);
}
v._finished = true;
v.parentNode.removeChild(v);
manager.finished(v.token);
}
function startTest(test, token) {
var type = getMajorMimeType(test.type);
if (type != "video")
return;
var v = document.createElement('video');
v.token = token;
manager.started(token);
v.src = test.name;
v._name = test.name;
v._finished = false;
v.autoplay = true;
v.style.display = "none";
v.addEventListener("loadeddata", loadeddata, false);
document.body.appendChild(v);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, beginTest);
function beginTest() {
manager.runTests(gAspectRatioTests, startTest);
}
</script>
</pre>
</body>
</html>

View File

@ -24,6 +24,7 @@ which makes Windows Media Foundation unavailable.
#include <mfidl.h>
#include <mfreadwrite.h>
#include <mfobjects.h>
#include <ks.h>
#include <stdio.h>
#include <mferror.h>
#include <propvarutil.h>

View File

@ -5,7 +5,6 @@
#include "mozilla/dom/SVGTextContentElement.h"
#include "nsISVGPoint.h"
#include "nsSVGTextContainerFrame.h"
#include "nsSVGTextFrame2.h"
#include "mozilla/dom/SVGIRect.h"
@ -28,12 +27,6 @@ nsSVGElement::LengthInfo SVGTextContentElement::sLengthInfo[1] =
{ &nsGkAtoms::textLength, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::XY }
};
nsSVGTextContainerFrame*
SVGTextContentElement::GetTextContainerFrame()
{
return do_QueryFrame(GetPrimaryFrame(Flush_Layout));
}
nsSVGTextFrame2*
SVGTextContentElement::GetSVGTextFrame()
{
@ -48,13 +41,6 @@ SVGTextContentElement::GetSVGTextFrame()
return nullptr;
}
bool
SVGTextContentElement::FrameIsSVGText()
{
nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
return frame && frame->IsSVGText();
}
already_AddRefed<SVGAnimatedLength>
SVGTextContentElement::TextLength()
{
@ -72,182 +58,102 @@ SVGTextContentElement::LengthAdjust()
int32_t
SVGTextContentElement::GetNumberOfChars()
{
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetNumberOfChars(this) : 0;
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
return metrics ? metrics->GetNumberOfChars() : 0;
}
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetNumberOfChars(this) : 0;
}
float
SVGTextContentElement::GetComputedTextLength()
{
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetComputedTextLength(this) : 0.0f;
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
return metrics ? metrics->GetComputedTextLength() : 0.0f;
}
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetComputedTextLength(this) : 0.0f;
}
void
SVGTextContentElement::SelectSubString(uint32_t charnum, uint32_t nchars, ErrorResult& rv)
{
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame)
return;
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame)
return;
rv = textFrame->SelectSubString(this, charnum, nchars);
} else {
rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
rv = textFrame->SelectSubString(this, charnum, nchars);
}
float
SVGTextContentElement::GetSubStringLength(uint32_t charnum, uint32_t nchars, ErrorResult& rv)
{
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame)
return 0.0f;
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame)
return 0.0f;
float length = 0.0f;
rv = textFrame->GetSubStringLength(this, charnum, nchars, &length);
return length;
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
if (!metrics)
return 0.0f;
uint32_t charcount = metrics->GetNumberOfChars();
if (charcount <= charnum || nchars > charcount - charnum) {
rv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return 0.0f;
}
if (nchars == 0)
return 0.0f;
return metrics->GetSubStringLength(charnum, nchars);
}
float length = 0.0f;
rv = textFrame->GetSubStringLength(this, charnum, nchars, &length);
return length;
}
already_AddRefed<nsISVGPoint>
SVGTextContentElement::GetStartPositionOfChar(uint32_t charnum, ErrorResult& rv)
{
nsCOMPtr<nsISVGPoint> point;
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = textFrame->GetStartPositionOfChar(this, charnum, getter_AddRefs(point));
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
if (!metrics) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = metrics->GetStartPositionOfChar(charnum, getter_AddRefs(point));
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsISVGPoint> point;
rv = textFrame->GetStartPositionOfChar(this, charnum, getter_AddRefs(point));
return point.forget();
}
already_AddRefed<nsISVGPoint>
SVGTextContentElement::GetEndPositionOfChar(uint32_t charnum, ErrorResult& rv)
{
nsCOMPtr<nsISVGPoint> point;
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = textFrame->GetEndPositionOfChar(this, charnum, getter_AddRefs(point));
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
if (!metrics) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = metrics->GetEndPositionOfChar(charnum, getter_AddRefs(point));
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsISVGPoint> point;
rv = textFrame->GetEndPositionOfChar(this, charnum, getter_AddRefs(point));
return point.forget();
}
already_AddRefed<SVGIRect>
SVGTextContentElement::GetExtentOfChar(uint32_t charnum, ErrorResult& rv)
{
nsRefPtr<SVGIRect> rect;
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = textFrame->GetExtentOfChar(this, charnum, getter_AddRefs(rect));
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
if (!metrics) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
rv = metrics->GetExtentOfChar(charnum, getter_AddRefs(rect));
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<SVGIRect> rect;
rv = textFrame->GetExtentOfChar(this, charnum, getter_AddRefs(rect));
return rect.forget();
}
float
SVGTextContentElement::GetRotationOfChar(uint32_t charnum, ErrorResult& rv)
{
float rotation;
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return 0.0f;
}
rv = textFrame->GetRotationOfChar(this, charnum, &rotation);
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
if (!metrics) {
rv.Throw(NS_ERROR_FAILURE);
return 0.0f;
}
rv = metrics->GetRotationOfChar(charnum, &rotation);
if (!textFrame) {
rv.Throw(NS_ERROR_FAILURE);
return 0.0f;
}
float rotation;
rv = textFrame->GetRotationOfChar(this, charnum, &rotation);
return rotation;
}
int32_t
SVGTextContentElement::GetCharNumAtPosition(nsISVGPoint& aPoint)
{
if (FrameIsSVGText()) {
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetCharNumAtPosition(this, &aPoint) : -1;
} else {
nsSVGTextContainerFrame* metrics = GetTextContainerFrame();
return metrics ? metrics->GetCharNumAtPosition(&aPoint) : -1;
}
nsSVGTextFrame2* textFrame = GetSVGTextFrame();
return textFrame ? textFrame->GetCharNumAtPosition(this, &aPoint) : -1;
}
} // namespace dom

View File

@ -15,7 +15,6 @@ static const unsigned short SVG_LENGTHADJUST_UNKNOWN = 0;
static const unsigned short SVG_LENGTHADJUST_SPACING = 1;
static const unsigned short SVG_LENGTHADJUST_SPACINGANDGLYPHS = 2;
class nsSVGTextContainerFrame;
class nsSVGTextFrame2;
namespace mozilla {
@ -51,9 +50,7 @@ protected:
: SVGTextContentElementBase(aNodeInfo)
{}
nsSVGTextContainerFrame* GetTextContainerFrame();
nsSVGTextFrame2* GetSVGTextFrame();
bool FrameIsSVGText();
enum { LENGTHADJUST };
virtual nsSVGEnum* EnumAttributes() = 0;

View File

@ -14,7 +14,6 @@
class nsIAtom;
class nsIContent;
class nsINodeInfo;
class nsSVGTextPathFrame;
nsresult NS_NewSVGTextPathElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
@ -35,7 +34,6 @@ typedef SVGTextContentElement SVGTextPathElementBase;
class SVGTextPathElement MOZ_FINAL : public SVGTextPathElementBase
{
friend class ::nsSVGTextPathFrame;
friend class ::nsSVGTextFrame2;
protected:

View File

@ -50,7 +50,6 @@ MOCHITEST_FILES = \
test_scientific.html \
scientific-helper.svg \
test_selectSubString.xhtml \
test_selectSubString2.xhtml \
selectSubString-helper.svg \
animated-svg-image-helper.html \
animated-svg-image-helper.svg \

View File

@ -23,9 +23,6 @@ function runTests()
{
var document = $("svg").contentWindow.document;
var text = document.getElementById("text");
// ensure that frames are generated with svg.text.css-frames.enabled
text.setAttribute("display", "none");
text.setAttribute("display", "block");
function expectThrow(charnum, nchars)
{
@ -62,14 +59,7 @@ function runTests()
SimpleTest.finish();
}
function run()
{
SpecialPowers.pushPrefEnv({'set': [['svg.text.css-frames.enabled', true]]},
runTests);
}
window.addEventListener("load", run, false);
window.addEventListener("load", runTests, false);
</script>
</pre>
</body>

View File

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=398825
-->
<head>
<title>Test for Bug 398825</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=398825">Mozilla Bug 398825</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<iframe id="svg" src="selectSubString-helper.svg"></iframe>
<pre id="test">
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
function runTests()
{
var document = $("svg").contentWindow.document;
var text = document.getElementById("text");
ok(!text.selectSubString, "unexpected selectSubString method");
SimpleTest.finish();
}
function run()
{
SpecialPowers.pushPrefEnv({'set': [['svg.text.css-frames.enabled', false]]},
runTests);
}
window.addEventListener("load", run, false);
</script>
</pre>
</body>
</html>

View File

@ -148,7 +148,7 @@ function runTest()
is(text3.getEndPositionOfChar(12).y, 253, "text3 char 12 end offset");
ok(text3.getExtentOfChar(12).y < 253, "text3 char 12 extent y");
ok(ymost(text3.getExtentOfChar(12)) > 253, "text3 char 12 extent height");
is(text3.getRotationOfChar(12), 180, "text3 char 12 rotation");
isfuzzy(text3.getRotationOfChar(12), 180, 0.001, "text3 char 12 rotation");
p.x = text3.getExtentOfChar(12).x + 0.1;
p.y = ymost(text3.getExtentOfChar(12)) - 0.1;
is(text3.getCharNumAtPosition(p), 12, "text3 finding char 12");

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=655877
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655877">Mozilla Bug 655877</a>
<p id="display"></p>
<div id="content" style="display: none">
<div id="content">
<svg width="400" height="200">
<text x="100" y="100" style="font: 16px sans-serif">
abc אבג 123 דהו defg
@ -29,32 +29,28 @@ function close(x, y, message) {
}
function runTest() {
SpecialPowers.pushPrefEnv({'set': [['svg.text.css-frames.enabled', true]]}, function() {
document.getElementById("content").style.display = "block";
var text = document.querySelector("text");
var text = document.querySelector("text");
// there are only 20 addressable characters
is(text.getNumberOfChars(), 20, "getNumberOfChars");
// there are only 20 addressable characters
is(text.getNumberOfChars(), 20, "getNumberOfChars");
var sum, total = text.getComputedTextLength();
var sum, total = text.getComputedTextLength();
close(text.getSubStringLength(0, 20), total, "getSubStringLength all");
close(text.getSubStringLength(0, 20), total, "getSubStringLength all");
// add the advance of each glyph
sum = 0;
for (var i = 0; i < 20; i++) {
sum += text.getSubStringLength(i, 1);
}
close(total, sum, "sum getSubStringLength 1");
// add the advance of each glyph
sum = 0;
for (var i = 0; i < 20; i++) {
sum += text.getSubStringLength(i, 1);
}
close(total, sum, "sum getSubStringLength 1");
// split the text up into three chunks and add them together
close(total, text.getSubStringLength(0, 6) +
text.getSubStringLength(6, 8) +
text.getSubStringLength(14, 6), "sum getSubStringLength 2");
// split the text up into three chunks and add them together
close(total, text.getSubStringLength(0, 6) +
text.getSubStringLength(6, 8) +
text.getSubStringLength(14, 6), "sum getSubStringLength 2");
SimpleTest.finish();
});
SimpleTest.finish();
}
window.addEventListener("load", runTest, false);

View File

@ -26,12 +26,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=886230
function runTest() {
var svgText = document.getElementById("t");
// Recreate the frames for the <text> with the pref set.
svgText.style.display = "none";
svgText.getComputedTextLength();
svgText.style.display = "inline";
svgText.getComputedTextLength();
// Dirty the frames.
document.getElementById("display").style.width = "700px";
svgText.removeChild(svgText.firstChild);
@ -44,9 +38,7 @@ function runTest() {
SimpleTest.finish();
}
window.addEventListener("load", function() {
SpecialPowers.pushPrefEnv({'set': [['svg.text.css-frames.enabled', true]]}, runTest);
}, false);
window.addEventListener("load", runTest, false);
SimpleTest.waitForExplicitFinish();
</script>

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569722
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=569722">Mozilla Bug 569722</a>
<p id="display"></p>
<div id="content" style="display: none">
<div id="content">
<svg width="400" height="200">
<text x="0" y="100" style="font: 16px sans-serif">aaa</text>
</svg>
@ -27,80 +27,76 @@ function close(x, y, message) {
}
function runTest() {
SpecialPowers.pushPrefEnv({'set': [['svg.text.css-frames.enabled', true]]}, function() {
document.getElementById("content").style.display = "block";
var text = document.querySelector("text");
var text = document.querySelector("text");
// get the original length
var length = text.getComputedTextLength();
// get the original length
var length = text.getComputedTextLength();
// get the original glyph positions
var startPositions = [],
endPositions = [],
extents = [];
for (var i = 0; i < 3; i++) {
startPositions.push(text.getStartPositionOfChar(i));
endPositions.push(text.getEndPositionOfChar(i));
extents.push(text.getExtentOfChar(i));
}
// get the original glyph positions
var startPositions = [],
endPositions = [],
extents = [];
// widths should all be the same
is(extents[0].width, extents[1].width);
is(extents[0].width, extents[2].width);
var checkCharNumAtPosition = function(x, y, i) {
var p = document.querySelector("svg").createSVGPoint();
p.x = x;
p.y = y;
is(text.getCharNumAtPosition(p), i, "getCharNumAtPosition(" + i + ")");
};
var checkPositions = function(start, end, width) {
for (var i = 0; i < 3; i++) {
startPositions.push(text.getStartPositionOfChar(i));
endPositions.push(text.getEndPositionOfChar(i));
extents.push(text.getExtentOfChar(i));
// check their positions
close(text.getStartPositionOfChar(i).x, start[i], "start position of glyph " + i);
close(text.getEndPositionOfChar(i).x, end[i], "end position of glyph " + i);
close(text.getExtentOfChar(i).x, start[i], "left edge of extent of glyph " + i);
close(text.getExtentOfChar(i).width, width, "width of glyph " + i);
checkCharNumAtPosition((start[i] + end[i]) / 2, 100, i);
}
}
// widths should all be the same
is(extents[0].width, extents[1].width);
is(extents[0].width, extents[2].width);
var w = extents[0].width;
var checkCharNumAtPosition = function(x, y, i) {
var p = document.querySelector("svg").createSVGPoint();
p.x = x;
p.y = y;
is(text.getCharNumAtPosition(p), i, "getCharNumAtPosition(" + i + ")");
};
var checkPositions = function(start, end, width) {
for (var i = 0; i < 3; i++) {
// check their positions
close(text.getStartPositionOfChar(i).x, start[i], "start position of glyph " + i);
close(text.getEndPositionOfChar(i).x, end[i], "end position of glyph " + i);
close(text.getExtentOfChar(i).x, start[i], "left edge of extent of glyph " + i);
close(text.getExtentOfChar(i).width, width, "width of glyph " + i);
checkCharNumAtPosition((start[i] + end[i]) / 2, 100, i);
}
}
var w = extents[0].width;
var doLengthAdjustSpacingTest = function() {
// getComputedTextLength should return the sum of the advances, and since
// we are just changing the positions of the glyphs, it should be the same
// as without a textLength="" attribute
close(text.getComputedTextLength(), length, "getComputedTextLength when lengthAdjust=\"spacing\"");
// expected start and end positions of the glyphs
var start = [0, 50 - w / 2, 100 - w];
var end = [w, 50 + w / 2, 100];
checkPositions(start, end, w);
};
// switch to adjust glyph positions, using the default value of lengthAdjust=""
text.setAttribute("textLength", "100");
doLengthAdjustSpacingTest();
// then with an explicit lengthAdjust="spacing"
text.setAttribute("lengthAdjust", "spacing");
doLengthAdjustSpacingTest();
// now test with lengthAdjust="spacingAndGlyphs"
text.setAttribute("lengthAdjust", "spacingAndGlyphs");
// now that each glyph is stretched, the total advance should be the textLength
close(text.getComputedTextLength(), 100, "getComputedTextLength when lengthAdjust=\"spacingAndGlyphs\"");
var doLengthAdjustSpacingTest = function() {
// getComputedTextLength should return the sum of the advances, and since
// we are just changing the positions of the glyphs, it should be the same
// as without a textLength="" attribute
close(text.getComputedTextLength(), length, "getComputedTextLength when lengthAdjust=\"spacing\"");
// expected start and end positions of the glyphs
var start = [0, 33.3333, 66.6666];
var end = [33.3333, 66.6666, 100];
checkPositions(start, end, 33.3333);
var start = [0, 50 - w / 2, 100 - w];
var end = [w, 50 + w / 2, 100];
checkPositions(start, end, w);
};
SimpleTest.finish();
});
// switch to adjust glyph positions, using the default value of lengthAdjust=""
text.setAttribute("textLength", "100");
doLengthAdjustSpacingTest();
// then with an explicit lengthAdjust="spacing"
text.setAttribute("lengthAdjust", "spacing");
doLengthAdjustSpacingTest();
// now test with lengthAdjust="spacingAndGlyphs"
text.setAttribute("lengthAdjust", "spacingAndGlyphs");
// now that each glyph is stretched, the total advance should be the textLength
close(text.getComputedTextLength(), 100, "getComputedTextLength when lengthAdjust=\"spacingAndGlyphs\"");
// expected start and end positions of the glyphs
var start = [0, 33.3333, 66.6666];
var end = [33.3333, 66.6666, 100];
checkPositions(start, end, 33.3333);
SimpleTest.finish();
}
window.addEventListener("load", runTest, false);

View File

@ -111,10 +111,10 @@ function runTest()
// character 12 should be on the bottom side
is(text2.getStartPositionOfChar(12).y, 860, "text2 char 12 start offset");
is(text2.getEndPositionOfChar(12).y, 860, "text2 char 12 end offset");
isfuzzy(text2.getEndPositionOfChar(12).y, 860, 0.001, "text2 char 12 end offset");
ok(text2.getExtentOfChar(12).y < 860, "text2 char 12 extent y");
ok(ymost(text2.getExtentOfChar(12)) > 860, "text2 char 12 extent height");
is(text2.getRotationOfChar(12), 180, "text2 char 12 rotation");
isfuzzy(text2.getRotationOfChar(12), 180, 0.001, "text2 char 12 rotation");
p.x = text2.getExtentOfChar(12).x + 0.1;
p.y = ymost(text2.getExtentOfChar(12)) - 0.1;
is(text2.getCharNumAtPosition(p), 12, "text2 finding char 12");

View File

@ -69,10 +69,6 @@ function testSelection()
var text = doc.getElementsByTagName("text");
// Display all the <text> elements.
var style = doc.getElementsByTagName("style")[0];
style.parentNode.removeChild(style);
// Drag to select the entire text element.
drag(101, 50, 99 + text[0].getComputedTextLength(), 50);
selection_is("hello there", "selecting entire simple text");
@ -134,8 +130,7 @@ function testSelection()
function runTest()
{
SpecialPowers.pushPrefEnv({ 'set': [['svg.text.css-frames.enabled', true]] },
testSelection);
SimpleTest.executeSoon(testSelection);
}
if (/Android/.test(navigator.userAgent)) {

View File

@ -1,12 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300"
style="font: 24px monospace">
<!-- Start with all text elements not displayed, so that we can flip
the CSS text frames pref and have the frames reconstructed. -->
<style>
text { display: none }
</style>
<!-- We need these two rects so that getBoundingClientRect of the <svg> does
not just return the region covered by the <text>, which would result in
the synthesizeMouse calls using the wrong positions. We don't use one

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -20,8 +20,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=456980
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.expectAssertions(1);
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {

View File

@ -39,9 +39,7 @@ function setCachePref(enabled) {
}
SimpleTest.expectAssertions(1);
/** Test for Bug 608669 **/
/** Test for Bug 608669 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(nextTest);

View File

@ -222,7 +222,7 @@ TCPSocketChild::SendSend(const JS::Value& aData,
return NS_ERROR_OUT_OF_MEMORY;
}
FallibleTArray<uint8_t> fallibleArr;
if (!fallibleArr.InsertElementsAt(0, data, nbytes)) {
if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InfallibleTArray<uint8_t> arr;

View File

@ -33,7 +33,7 @@ interface SVGTextContentElement : SVGGraphicsElement {
[Throws]
float getRotationOfChar(unsigned long charnum);
long getCharNumAtPosition(SVGPoint point);
[Throws, Pref="svg.text.css-frames.enabled"]
[Throws]
void selectSubString(unsigned long charnum, unsigned long nchars);
};

View File

@ -13,6 +13,8 @@ include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(topsrcdir)/extensions/spellcheck/src
ifdef MOZ_NATIVE_HUNSPELL
# MOZ_HUNSPELL_CFLAGS is extracted through pkgconfig during configure,
# even though the variable doesn't show up in configure.in.
CXXFLAGS += $(MOZ_HUNSPELL_CFLAGS)
endif

View File

@ -79,13 +79,22 @@ public:
~Log() { mMessage << '\n'; WriteLog(mMessage.str()); }
Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; }
Log &operator <<(const char aStr[]) { mMessage << static_cast<const char*>(aStr); return *this; }
Log &operator <<(bool aBool) { mMessage << (aBool ? "true" : "false"); return *this; }
Log &operator <<(int aInt) { mMessage << aInt; return *this; }
Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; }
Log &operator <<(Float aFloat) { mMessage << aFloat; return *this; }
Log &operator <<(double aDouble) { mMessage << aDouble; return *this; }
Log &operator <<(const Point &aPoint)
{ mMessage << "Point(" << aPoint.x << "," << aPoint.y << ")"; return *this; }
Log &operator <<(const Size &aSize)
{ mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
{ mMessage << "Size(" << aSize.width << "," << aSize.height << ")"; return *this; }
Log &operator <<(const IntSize &aSize)
{ mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
{ mMessage << "IntSize(" << aSize.width << "," << aSize.height << ")"; return *this; }
Log &operator <<(const Rect &aRect)
{ mMessage << "Rect(" << aRect.x << "," << aRect.y << "," << aRect.width << "," << aRect.height << ")"; return *this; }
Log &operator<<(const Matrix& aMatrix)
{ mMessage << "[ " << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << " ]"; return *this; }
{ mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")"; return *this; }
private:

View File

@ -207,8 +207,8 @@ GLXLibrary::EnsureInitialized(LibType libType)
// Not possible to query for extensions.
return false;
const char *clientVendor = xGetClientString(display, GLX_VENDOR);
const char *serverVendor = xQueryServerString(display, screen, GLX_VENDOR);
const char *clientVendor = xGetClientString(display, LOCAL_GLX_VENDOR);
const char *serverVendor = xQueryServerString(display, screen, LOCAL_GLX_VENDOR);
const char *extensionsStr = xQueryExtensionsString(display, screen);
GLLibraryLoader::SymLoadStruct *sym13;
@ -303,12 +303,12 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
NS_ASSERTION((1 << alphaSize) - 1 == direct.alphaMask,
"Unexpected render format with non-adjacent alpha bits");
int attribs[] = { GLX_DOUBLEBUFFER, False,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_ALPHA_SIZE, alphaSize,
(alphaSize ? GLX_BIND_TO_TEXTURE_RGBA_EXT
: GLX_BIND_TO_TEXTURE_RGB_EXT), True,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
int attribs[] = { LOCAL_GLX_DOUBLEBUFFER, False,
LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT,
LOCAL_GLX_ALPHA_SIZE, alphaSize,
(alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT
: LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True,
LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT,
None };
int numConfigs = 0;
@ -334,7 +334,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
for (int i = 0; i < numConfigs; i++) {
int id = None;
sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &id);
sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id);
Visual *visual;
int depth;
FindVisualAndDepth(display, id, &visual, &depth);
@ -382,7 +382,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
// situations (ATI) where there are no fbconfigs without alpha bits.
//
// glXChooseFBConfig should prefer configs with smaller
// GLX_BUFFER_SIZE, so we should still get zero alpha bits if
// LOCAL_GLX_BUFFER_SIZE, so we should still get zero alpha bits if
// available, except perhaps with NVIDIA drivers where buffer size is
// not the specified sum of the component sizes.
if (haveNonColorBits) {
@ -392,7 +392,7 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
// matches.
int size = 0;
sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i],
GLX_ALPHA_SIZE, &size);
LOCAL_GLX_ALPHA_SIZE, &size);
if (size != alphaSize) {
continue;
}
@ -409,10 +409,10 @@ GLXLibrary::CreatePixmap(gfxASurface* aSurface)
return None;
}
int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT,
(alphaSize ? GLX_TEXTURE_FORMAT_RGBA_EXT
: GLX_TEXTURE_FORMAT_RGB_EXT),
int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT,
LOCAL_GLX_TEXTURE_FORMAT_EXT,
(alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT
: LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT),
None};
GLXPixmap glxpixmap = xCreatePixmap(display,
@ -451,7 +451,7 @@ GLXLibrary::BindTexImage(GLXPixmap aPixmap)
} else {
xWaitX();
}
xBindTexImage(display, aPixmap, GLX_FRONT_LEFT_EXT, nullptr);
xBindTexImage(display, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT, nullptr);
}
void
@ -462,7 +462,7 @@ GLXLibrary::ReleaseTexImage(GLXPixmap aPixmap)
}
Display *display = DefaultXDisplay();
xReleaseTexImage(display, aPixmap, GLX_FRONT_LEFT_EXT);
xReleaseTexImage(display, aPixmap, LOCAL_GLX_FRONT_LEFT_EXT);
}
#ifdef DEBUG
@ -761,8 +761,8 @@ public:
int db = 0;
int err = glx.xGetFBConfigAttrib(display, cfg,
GLX_DOUBLEBUFFER, &db);
if (GLX_BAD_ATTRIBUTE != err) {
LOCAL_GLX_DOUBLEBUFFER, &db);
if (LOCAL_GLX_BAD_ATTRIBUTE != err) {
#ifdef DEBUG
if (DebugMode()) {
printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
@ -798,7 +798,7 @@ TRY_AGAIN_NO_SHARING:
context = glx.xCreateNewContext(
display,
cfg,
GLX_RGBA_TYPE,
LOCAL_GLX_RGBA_TYPE,
glxContext,
True);
}
@ -1208,7 +1208,7 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
if (sDefGLXLib.IsATI() ||
!sDefGLXLib.GLXVersionCheck(1, 3)) {
const int attribs[] = {
GLX_DOUBLEBUFFER, False,
LOCAL_GLX_DOUBLEBUFFER, False,
0
};
cfgs = sDefGLXLib.xChooseFBConfig(display,
@ -1227,7 +1227,7 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
}
NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");
// XXX the visual ID is almost certainly the GLX_FBCONFIG_ID, so
// XXX the visual ID is almost certainly the LOCAL_GLX_FBCONFIG_ID, so
// we could probably do this first and replace the glXGetFBConfigs
// with glXChooseConfigs. Docs are sparklingly clear as always.
XWindowAttributes widgetAttrs;
@ -1244,7 +1244,7 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
for (int i = 0; i < numConfigs; i++) {
int visid = None;
sDefGLXLib.xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &visid);
sDefGLXLib.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid);
if (!visid) {
continue;
}
@ -1297,8 +1297,8 @@ CreateOffscreenPixmapContext(const gfxIntSize& size, LibType libToUse)
int xscreen = DefaultScreen(display);
int attribs[] = {
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_X_RENDERABLE, True,
LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT,
LOCAL_GLX_X_RENDERABLE, True,
0
};
int numConfigs = 0;
@ -1321,12 +1321,12 @@ CreateOffscreenPixmapContext(const gfxIntSize& size, LibType libToUse)
for (int i = 0; i < numConfigs; ++i) {
int dtype;
if (glx.xGetFBConfigAttrib(display, cfgs[i], GLX_DRAWABLE_TYPE, &dtype) != Success
|| !(dtype & GLX_PIXMAP_BIT))
if (glx.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_DRAWABLE_TYPE, &dtype) != Success
|| !(dtype & LOCAL_GLX_PIXMAP_BIT))
{
continue;
}
if (glx.xGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &visid) != Success
if (glx.xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &visid) != Success
|| visid == 0)
{
continue;

View File

@ -8,7 +8,19 @@
#include "GLContextTypes.h"
typedef realGLboolean GLboolean;
#include <GL/glx.h>
// stuff from glx.h
#include "X11/Xlib.h"
typedef struct __GLXcontextRec *GLXContext;
typedef XID GLXPixmap;
typedef XID GLXDrawable;
/* GLX 1.3 and later */
typedef struct __GLXFBConfigRec *GLXFBConfig;
typedef XID GLXFBConfigID;
typedef XID GLXContextID;
typedef XID GLXWindow;
typedef XID GLXPbuffer;
// end of stuff from glx.h
struct PRLibrary;

View File

@ -5,6 +5,9 @@
* found in the LICENSE file.
*/
#ifndef SkImages_DEFINED
#define SkImages_DEFINED
class SkImages {
public:
/**
@ -12,3 +15,5 @@ public:
*/
static void InitializeFlattenables();
};
#endif

View File

@ -151,57 +151,69 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXPORTS.skia += [
'include/ports/SkTypeface_mac.h',
]
SOURCES += [
'src/ports/SkFontHost_mac.cpp',
UNIFIED_SOURCES += [
'src/ports/SkThread_pthread.cpp',
'src/ports/SkTime_Unix.cpp',
'src/utils/mac/SkStream_mac.cpp',
'src/utils/SkThreadUtils_pthread.cpp',
'src/utils/SkThreadUtils_pthread_mach.cpp',
]
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/ports/SkFontHost_mac.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS.skia += [
'include/config/sk_stdint.h',
'include/ports/SkTypeface_win.h',
]
SOURCES += [
'src/ports/SkFontHost_sandbox_none.cpp',
'src/ports/SkFontHost_win.cpp',
UNIFIED_SOURCES += [
'src/ports/SkThread_win.cpp',
'src/ports/SkTime_win.cpp',
'src/utils/SkThreadUtils_win.cpp',
]
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/ports/SkFontHost_sandbox_none.cpp',
'src/ports/SkFontHost_win.cpp',
]
elif CONFIG['MOZ_WIDGET_GTK']:
EXPORTS.skia += [
'include/ports/SkTypeface_cairo.h',
]
SOURCES += [
'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
UNIFIED_SOURCES += [
'src/ports/SkThread_pthread.cpp',
'src/ports/SkTime_Unix.cpp',
'src/utils/SkOSFile.cpp',
'src/utils/SkThreadUtils_pthread.cpp',
]
if CONFIG['OS_TARGET'] in ('Linux', 'FreeBSD', 'NetBSD'):
SOURCES += [
'src/utils/SkThreadUtils_pthread_linux.cpp',
]
else:
SOURCES += [
'src/utils/SkThreadUtils_pthread_other.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
]
if CONFIG['OS_TARGET'] in ('Linux', 'FreeBSD', 'NetBSD'):
UNIFIED_SOURCES += [
'src/utils/SkThreadUtils_pthread_linux.cpp',
]
else:
UNIFIED_SOURCES += [
'src/utils/SkThreadUtils_pthread_other.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
UNIFIED_SOURCES += [
'src/utils/SkOSFile.cpp',
]
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
]
if CONFIG['OS_TARGET'] == 'Linux':
EXPORTS.skia += [
'include/ports/SkTypeface_cairo.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'src/ports/SkThread_pthread.cpp',
'src/ports/SkTime_Unix.cpp',
'src/utils/SkThreadUtils_pthread.cpp',
@ -213,13 +225,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
EXPORTS.skia += [
'include/ports/SkTypeface_cairo.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'src/images/SkImageRef_ashmem.cpp',
'src/ports/SkDebug_android.cpp',
'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
'src/ports/SkFontHost_linux.cpp',
'src/ports/SkThread_pthread.cpp',
'src/ports/SkTime_Unix.cpp',
'src/utils/android/ashmem.cpp',
@ -227,12 +235,22 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
'src/utils/SkThreadUtils_pthread.cpp',
'src/utils/SkThreadUtils_pthread_other.cpp',
]
else:
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/ports/SkFontHost_cairo.cpp',
'src/ports/SkFontHost_FreeType.cpp',
'src/ports/SkFontHost_FreeType_common.cpp',
'src/ports/SkFontHost_linux.cpp',
]
else:
UNIFIED_SOURCES += [
'src/ports/SkDebug_stdio.cpp',
]
if CONFIG['INTEL_ARCHITECTURE']:
# We need to build SSE2-enabled files separately so that we're able
# to pass -msse2 for them. We won't be able to unify them with the rest,
# but we should at least be able to unify them with each other.
SOURCES += [
'src/opts/opts_check_SSE2.cpp',
'src/opts/SkBitmapProcState_opts_SSE2.cpp',
@ -245,20 +263,24 @@ if CONFIG['INTEL_ARCHITECTURE']:
'src/opts/SkBitmapProcState_opts_SSSE3.cpp',
]
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
SOURCES += [
UNIFIED_SOURCES += [
'src/opts/opts_check_arm.cpp',
'src/opts/SkBitmapProcState_opts_arm.cpp',
'src/opts/SkBlitRow_opts_arm.cpp',
]
SOURCES += [
'src/opts/SkBitmapProcState_opts_arm.cpp',
]
else:
SOURCES += [
'src/opts/SkBitmapProcState_opts_none.cpp',
UNIFIED_SOURCES += [
'src/opts/SkBlitRow_opts_none.cpp',
'src/opts/SkUtils_opts_none.cpp',
]
SOURCES += [
'src/opts/SkBitmapProcState_opts_none.cpp',
]
if CONFIG['MOZ_ENABLE_SKIA_GPU']:
SOURCES += [
UNIFIED_SOURCES += [
'src/gpu/effects/GrConfigConversionEffect.cpp',
'src/gpu/effects/GrConvolutionEffect.cpp',
'src/gpu/effects/GrSimpleTextureEffect.cpp',
@ -342,7 +364,7 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'src/gpu/SkGrTexturePixelRef.cpp',
]
SOURCES += [
UNIFIED_SOURCES += [
'src/core/Sk64.cpp',
'src/core/SkAAClip.cpp',
'src/core/SkAdvancedTypefaceMetrics.cpp',
@ -356,19 +378,12 @@ SOURCES += [
'src/core/SkBitmapHeap.cpp',
'src/core/SkBitmapProcShader.cpp',
'src/core/SkBitmapProcState.cpp',
'src/core/SkBitmapProcState_matrixProcs.cpp',
'src/core/SkBitmapSampler.cpp',
'src/core/SkBlitMask_D32.cpp',
'src/core/SkBlitRow_D16.cpp',
'src/core/SkBlitRow_D32.cpp',
'src/core/SkBlitRow_D4444.cpp',
'src/core/SkBlitter.cpp',
'src/core/SkBlitter_4444.cpp',
'src/core/SkBlitter_A1.cpp',
'src/core/SkBlitter_A8.cpp',
'src/core/SkBlitter_ARGB32.cpp',
'src/core/SkBlitter_RGB16.cpp',
'src/core/SkBlitter_Sprite.cpp',
'src/core/SkBuffer.cpp',
'src/core/SkCanvas.cpp',
'src/core/SkChunkAlloc.cpp',
@ -443,10 +458,6 @@ SOURCES += [
'src/core/SkScalar.cpp',
'src/core/SkScalerContext.cpp',
'src/core/SkScan.cpp',
'src/core/SkScan_Antihair.cpp',
'src/core/SkScan_AntiPath.cpp',
'src/core/SkScan_Hairline.cpp',
'src/core/SkScan_Path.cpp',
'src/core/SkShader.cpp',
'src/core/SkSpriteBlitter_ARGB32.cpp',
'src/core/SkSpriteBlitter_RGB16.cpp',
@ -472,8 +483,6 @@ SOURCES += [
'src/effects/gradients/SkLinearGradient.cpp',
'src/effects/gradients/SkRadialGradient.cpp',
'src/effects/gradients/SkSweepGradient.cpp',
'src/effects/gradients/SkTwoPointConicalGradient.cpp',
'src/effects/gradients/SkTwoPointRadialGradient.cpp',
'src/effects/Sk1DPathEffect.cpp',
'src/effects/Sk2DPathEffect.cpp',
'src/effects/SkAvoidXfermode.cpp',
@ -534,7 +543,6 @@ SOURCES += [
'src/utils/SkBase64.cpp',
'src/utils/SkBitmapTransformer.cpp',
'src/utils/SkBitSet.cpp',
'src/utils/SkCondVar.cpp',
'src/utils/SkCountdown.cpp',
'src/utils/SkDeferredCanvas.cpp',
'src/utils/SkPictureUtils.cpp',
@ -542,6 +550,36 @@ SOURCES += [
'src/utils/SkThreadPool.cpp',
]
# left out of UNIFIED_SOURCES for now to avoid having to patch skia. Should revisit eventually.
SOURCES += [
'src/core/SkBitmapProcState_matrixProcs.cpp',
'src/core/SkBlitter_4444.cpp',
'src/core/SkBlitter_A1.cpp',
'src/core/SkBlitter_A8.cpp',
'src/core/SkBlitter_ARGB32.cpp',
'src/core/SkBlitter_RGB16.cpp',
'src/core/SkBlitter_Sprite.cpp',
'src/core/SkScan_Antihair.cpp',
'src/core/SkScan_AntiPath.cpp',
'src/core/SkScan_Hairline.cpp',
'src/core/SkScan_Path.cpp',
'src/effects/gradients/SkTwoPointConicalGradient.cpp',
'src/effects/gradients/SkTwoPointRadialGradient.cpp',
]
# On Windows, SkCondVar needs to be built separately because it relies on
# windows.h providing such functions as InitializeConditionVariable.
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [
'src/utils/SkCondVar.cpp',
]
else:
UNIFIED_SOURCES += [
'src/utils/SkCondVar.cpp',
]
# left out of UNIFIED_SOURCES for now; that's not C++ anyway, nothing else to unify it with
if not CONFIG['INTEL_ARCHITECTURE'] and CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
SOURCES += [
'src/opts/memset.arm.S',

View File

@ -0,0 +1,94 @@
# HG changeset patch
# Parent 979e60d9c09f22eb139643da6de7568b603e1aa1
diff --git a/gfx/skia/include/images/SkImages.h b/gfx/skia/include/images/SkImages.h
--- a/gfx/skia/include/images/SkImages.h
+++ b/gfx/skia/include/images/SkImages.h
@@ -1,14 +1,19 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#ifndef SkImages_DEFINED
+#define SkImages_DEFINED
+
class SkImages {
public:
/**
* Initializes flattenables in the images project.
*/
static void InitializeFlattenables();
};
+
+#endif
diff --git a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
--- a/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
+++ b/gfx/skia/src/gpu/GrAAConvexPathRenderer.h
@@ -1,16 +1,19 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#ifndef GrAAConvexPathRenderer_DEFINED
+#define GrAAConvexPathRenderer_DEFINED
+
#include "GrPathRenderer.h"
class GrAAConvexPathRenderer : public GrPathRenderer {
public:
GrAAConvexPathRenderer();
virtual bool canDrawPath(const SkPath& path,
@@ -19,8 +22,10 @@ public:
bool antiAlias) const SK_OVERRIDE;
protected:
virtual bool onDrawPath(const SkPath& path,
const SkStrokeRec& stroke,
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
};
+
+#endif
diff --git a/gfx/skia/src/gpu/GrReducedClip.h b/gfx/skia/src/gpu/GrReducedClip.h
--- a/gfx/skia/src/gpu/GrReducedClip.h
+++ b/gfx/skia/src/gpu/GrReducedClip.h
@@ -1,16 +1,19 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+#ifndef GrReducedClip_DEFINED
+#define GrReducedClip_DEFINED
+
#include "SkClipStack.h"
#include "SkTLList.h"
namespace GrReducedClip {
typedef SkTLList<SkClipStack::Element> ElementList;
enum InitialState {
@@ -33,8 +36,10 @@ enum InitialState {
void ReduceClipStack(const SkClipStack& stack,
const SkIRect& queryBounds,
ElementList* result,
InitialState* initialState,
SkIRect* tighterBounds = NULL,
bool* requiresAA = NULL);
} // namespace GrReducedClip
+
+#endif

View File

@ -6,6 +6,9 @@
* found in the LICENSE file.
*/
#ifndef GrAAConvexPathRenderer_DEFINED
#define GrAAConvexPathRenderer_DEFINED
#include "GrPathRenderer.h"
@ -24,3 +27,5 @@ protected:
GrDrawTarget* target,
bool antiAlias) SK_OVERRIDE;
};
#endif

View File

@ -6,6 +6,9 @@
* found in the LICENSE file.
*/
#ifndef GrReducedClip_DEFINED
#define GrReducedClip_DEFINED
#include "SkClipStack.h"
#include "SkTLList.h"
@ -38,3 +41,5 @@ void ReduceClipStack(const SkClipStack& stack,
bool* requiresAA = NULL);
} // namespace GrReducedClip
#endif

View File

@ -12,6 +12,9 @@
#include "gfxXlibSurface.h"
#endif
using namespace mozilla;
using namespace mozilla::gfx;
gfxSurfaceDrawable::gfxSurfaceDrawable(gfxASurface* aSurface,
const gfxIntSize aSize,
const gfxMatrix aTransform)
@ -21,6 +24,15 @@ gfxSurfaceDrawable::gfxSurfaceDrawable(gfxASurface* aSurface,
{
}
gfxSurfaceDrawable::gfxSurfaceDrawable(DrawTarget* aDrawTarget,
const gfxIntSize aSize,
const gfxMatrix aTransform)
: gfxDrawable(aSize)
, mDrawTarget(aDrawTarget)
, mTransform(aTransform)
{
}
static gfxMatrix
DeviceToImageTransform(gfxContext* aContext,
const gfxMatrix& aUserSpaceToImageSpace)
@ -105,7 +117,19 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
const GraphicsFilter& aFilter,
const gfxMatrix& aTransform)
{
nsRefPtr<gfxPattern> pattern = new gfxPattern(mSurface);
nsRefPtr<gfxPattern> pattern;
if (mDrawTarget) {
if (aContext->IsCairo()) {
nsRefPtr<gfxASurface> source =
gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
pattern = new gfxPattern(source);
} else {
RefPtr<SourceSurface> source = mDrawTarget->Snapshot();
pattern = new gfxPattern(source, Matrix());
}
} else {
pattern = new gfxPattern(mSurface);
}
if (aRepeat) {
pattern->SetExtend(gfxPattern::EXTEND_REPEAT);
pattern->SetFilter(aFilter);
@ -136,6 +160,13 @@ gfxSurfaceDrawable::Draw(gfxContext* aContext,
already_AddRefed<gfxImageSurface>
gfxSurfaceDrawable::GetAsImageSurface()
{
if (mDrawTarget) {
// TODO: Find a way to implement this. The caller really wants a 'sub-image' of
// the original, without having to do a copy. GetDataSurface() might just copy,
// which isn't useful.
return nullptr;
}
return mSurface->GetAsImageSurface();
}

View File

@ -10,6 +10,7 @@
#include "gfxRect.h"
#include "gfxMatrix.h"
#include "GraphicsFilter.h"
#include "mozilla/gfx/2D.h"
class gfxASurface;
class gfxImageSurface;
@ -55,6 +56,8 @@ class gfxSurfaceDrawable : public gfxDrawable {
public:
gfxSurfaceDrawable(gfxASurface* aSurface, const gfxIntSize aSize,
const gfxMatrix aTransform = gfxMatrix());
gfxSurfaceDrawable(mozilla::gfx::DrawTarget* aDT, const gfxIntSize aSize,
const gfxMatrix aTransform = gfxMatrix());
virtual ~gfxSurfaceDrawable() {}
virtual bool Draw(gfxContext* aContext,
@ -67,6 +70,7 @@ public:
protected:
nsRefPtr<gfxASurface> mSurface;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
const gfxMatrix mTransform;
};

View File

@ -4,9 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxPath.h"
#include "gfxPoint.h"
#include "gfxPlatform.h"
#include "gfxASurface.h"
#include "mozilla/gfx/2D.h"
#include "cairo.h"
@ -15,13 +12,11 @@ using namespace mozilla::gfx;
gfxPath::gfxPath(cairo_path_t* aPath)
: mPath(aPath)
, mFlattenedPath(nullptr)
{
}
gfxPath::gfxPath(Path* aPath)
: mPath(nullptr)
, mFlattenedPath(nullptr)
, mMoz2DPath(aPath)
{
}
@ -29,126 +24,4 @@ gfxPath::gfxPath(Path* aPath)
gfxPath::~gfxPath()
{
cairo_path_destroy(mPath);
cairo_path_destroy(mFlattenedPath);
}
void
gfxPath::EnsureFlattenedPath()
{
if (mFlattenedPath) {
return;
}
gfxASurface* surf = gfxPlatform::GetPlatform()->ScreenReferenceSurface();
cairo_t* cr = cairo_create(surf->CairoSurface());
cairo_append_path(cr, mPath);
mFlattenedPath = cairo_copy_path_flat(cr);
cairo_destroy(cr);
}
static gfxFloat
CalcSubLengthAndAdvance(cairo_path_data_t *aData,
gfxPoint &aPathStart, gfxPoint &aCurrent)
{
float sublength = 0;
switch (aData->header.type) {
case CAIRO_PATH_MOVE_TO:
{
aCurrent = aPathStart = gfxPoint(aData[1].point.x,
aData[1].point.y);
break;
}
case CAIRO_PATH_LINE_TO:
{
gfxPoint diff =
gfxPoint(aData[1].point.x, aData[1].point.y) - aCurrent;
sublength = sqrt(diff.x * diff.x + diff.y * diff.y);
aCurrent = gfxPoint(aData[1].point.x, aData[1].point.y);
break;
}
case CAIRO_PATH_CURVE_TO:
/* should never happen with a flattened path */
NS_WARNING("curve_to in flattened path");
break;
case CAIRO_PATH_CLOSE_PATH:
{
gfxPoint diff = aPathStart - aCurrent;
sublength = sqrt(diff.x * diff.x + diff.y * diff.y);
aCurrent = aPathStart;
break;
}
}
return sublength;
}
gfxFloat
gfxPath::GetLength()
{
if (mMoz2DPath) {
return mMoz2DPath->ComputeLength();
}
EnsureFlattenedPath();
gfxPoint start(0, 0); // start of current subpath
gfxPoint current(0, 0); // current point
gfxFloat length = 0; // current summed length
for (int32_t i = 0;
i < mFlattenedPath->num_data;
i += mFlattenedPath->data[i].header.length) {
length += CalcSubLengthAndAdvance(&mFlattenedPath->data[i], start, current);
}
return length;
}
gfxPoint
gfxPath::FindPoint(gfxPoint aOffset, gfxFloat *aAngle)
{
if (mMoz2DPath) {
Point tangent; // Unit vector tangent to the point we find.
Point result = mMoz2DPath->ComputePointAtLength(aOffset.x, &tangent);
// The y value of aOffset is the offset along the normal vector to apply
Point normal(-tangent.y, tangent.x);
result += normal * aOffset.y;
if (aAngle)
*aAngle = atan2(tangent.y, tangent.x);
return gfxPoint(result.x, result.y);
}
EnsureFlattenedPath();
gfxPoint start(0, 0); // start of current subpath
gfxPoint current(0, 0); // current point
gfxFloat length = 0; // current summed length
for (int32_t i = 0;
i < mFlattenedPath->num_data;
i += mFlattenedPath->data[i].header.length) {
gfxPoint prev = current;
gfxFloat sublength = CalcSubLengthAndAdvance(&mFlattenedPath->data[i],
start, current);
gfxPoint diff = current - prev;
if (aAngle)
*aAngle = atan2(diff.y, diff.x);
if (sublength != 0 && length + sublength >= aOffset.x) {
gfxFloat ratio = (aOffset.x - length) / sublength;
gfxFloat normalization =
1.0 / sqrt(diff.x * diff.x + diff.y * diff.y);
return prev * (1.0f - ratio) + current * ratio +
gfxPoint(-diff.y, diff.x) * aOffset.y * normalization;
}
length += sublength;
}
// requested offset is past the end of the path - return last point
return current;
}

View File

@ -11,7 +11,6 @@
#include "mozilla/RefPtr.h"
class gfxContext;
struct gfxPoint;
typedef struct cairo_path cairo_path_t;
namespace mozilla {
@ -29,33 +28,14 @@ class gfxPath {
friend class gfxContext;
protected:
gfxPath(cairo_path_t* aPath);
void EnsureFlattenedPath();
public:
gfxPath(mozilla::gfx::Path* aPath);
virtual ~gfxPath();
/**
* Returns calculated total length of path
*/
gfxFloat GetLength();
/**
* Returns a point a certain distance along the path. Return is
* first or last point of the path if the requested length offset
* is outside the range for the path.
* @param aOffset offset inpath parameter space (x=length, y=normal offset)
* @param aAngle optional - output tangent
*/
gfxPoint FindPoint(gfxPoint aOffset,
gfxFloat* aAngle = nullptr);
protected:
private:
cairo_path_t* mPath;
cairo_path_t* mFlattenedPath;
mozilla::RefPtr<mozilla::gfx::Path> mMoz2DPath;
};

View File

@ -12,6 +12,7 @@
#include "ycbcr_to_rgb565.h"
#include "GeckoProfiler.h"
#include "ImageContainer.h"
#include "gfx2DGlue.h"
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
@ -246,26 +247,28 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
if (needed.IsEmpty())
return nullptr;
nsRefPtr<gfxASurface> temp;
nsRefPtr<gfxDrawable> drawable;
gfxIntSize size(int32_t(needed.Width()), int32_t(needed.Height()));
nsRefPtr<gfxImageSurface> image = aDrawable->GetAsImageSurface();
if (image && gfxRect(0, 0, image->GetSize().width, image->GetSize().height).Contains(needed)) {
temp = image->GetSubimage(needed);
nsRefPtr<gfxASurface> temp = image->GetSubimage(needed);
drawable = new gfxSurfaceDrawable(temp, size, gfxMatrix().Translate(-needed.TopLeft()));
} else {
temp =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxASurface::ContentFromFormat(aFormat));
if (!temp || temp->CairoStatus())
return nullptr;
mozilla::RefPtr<mozilla::gfx::DrawTarget> target =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(ToIntSize(size),
ImageFormatToSurfaceFormat(aFormat));
if (!target) {
return nullptr;
}
nsRefPtr<gfxContext> tmpCtx = new gfxContext(temp);
nsRefPtr<gfxContext> tmpCtx = new gfxContext(target);
tmpCtx->SetOperator(OptimalFillOperator());
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true,
GraphicsFilter::FILTER_FAST, gfxMatrix().Translate(needed.TopLeft()));
drawable = new gfxSurfaceDrawable(target, size, gfxMatrix().Translate(-needed.TopLeft()));
}
nsRefPtr<gfxDrawable> drawable =
new gfxSurfaceDrawable(temp, size, gfxMatrix().Translate(-needed.TopLeft()));
return drawable.forget();
}
#endif // !MOZ_GFX_OPTIMIZE_MOBILE

View File

@ -154,9 +154,7 @@ public:
already_AddRefed<gfxDrawable> Drawable() const
{
nsRefPtr<gfxASurface> surface =
gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget);
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, mTargetSize);
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(mTarget, mTargetSize);
return drawable.forget();
}

View File

@ -834,46 +834,17 @@ VectorImage::CreateDrawableAndShow(const SVGDrawingParameters& aParams)
return Show(svgDrawable, aParams);
// Try to create an offscreen surface.
mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
nsRefPtr<gfxContext> ctx;
nsRefPtr<gfxASurface> surface;
if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(aParams.imageRect.Size(), gfx::FORMAT_B8G8R8A8);
// XXX(seth): All of this ugliness (the backend check, |surface|, the
// GetThebesSurfaceForDrawTarget call) is needed because we can't use Moz2D
// for drawing in all cases yet. See bug 923341.
if (target) {
switch (target->GetType()) {
case mozilla::gfx::BACKEND_DIRECT2D:
case mozilla::gfx::BACKEND_DIRECT2D1_1:
case mozilla::gfx::BACKEND_SKIA:
// Can't cache on this backend.
return Show(svgDrawable, aParams);
default:
surface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(target);
ctx = new gfxContext(target);
}
}
} else {
target = gfxPlatform::GetPlatform()->
CreateOffscreenCanvasDrawTarget(aParams.imageRect.Size(), gfx::FORMAT_B8G8R8A8);
surface = target ? gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(target)
: nullptr;
ctx = surface ? new gfxContext(surface) : nullptr;
}
mozilla::RefPtr<mozilla::gfx::DrawTarget> target =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(aParams.imageRect.Size(), gfx::FORMAT_B8G8R8A8);
// If we couldn't create the draw target, it was probably because it would end
// up way too big. Generally it also wouldn't fit in the cache, but the prefs
// could be set such that the cache isn't the limiting factor. If we couldn't
// create the surface, we are on a platform that does not support
// GetThebesSurfaceForDrawTarget. This will be fixed in bug 923341.
if (!target || !surface)
// could be set such that the cache isn't the limiting factor.
if (!target)
return Show(svgDrawable, aParams);
nsRefPtr<gfxContext> ctx = new gfxContext(target);
// Actually draw. (We use FILTER_NEAREST since we never scale here.)
gfxUtils::DrawPixelSnapped(ctx, svgDrawable, gfxMatrix(),
aParams.imageRect, aParams.imageRect,
@ -891,7 +862,7 @@ VectorImage::CreateDrawableAndShow(const SVGDrawingParameters& aParams)
// Draw. Note that if SurfaceCache::Insert failed for whatever reason,
// then |target| is all that is keeping the pixel data alive, so we have
// to draw before returning from this function.
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, aParams.imageRect.Size());
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(target, aParams.imageRect.Size());
Show(drawable, aParams);
}

View File

@ -19,203 +19,6 @@
using namespace mozilla::image;
class imgStatusTrackerNotifyingObserver : public imgDecoderObserver
{
public:
imgStatusTrackerNotifyingObserver(imgStatusTracker* aTracker)
: mTracker(aTracker)
{
MOZ_ASSERT(aTracker);
}
virtual ~imgStatusTrackerNotifyingObserver() {}
void SetTracker(imgStatusTracker* aTracker)
{
MOZ_ASSERT(aTracker);
mTracker = aTracker;
}
/** imgDecoderObserver methods **/
virtual void OnStartDecode()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::OnStartDecode");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnStartDecode callback before we've created our image");
mTracker->RecordStartDecode();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStartDecode(iter.GetNext());
}
if (!mTracker->IsMultipart()) {
mTracker->RecordBlockOnload();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendBlockOnload(iter.GetNext());
}
}
}
virtual void OnStartRequest()
{
NS_NOTREACHED("imgStatusTrackerNotifyingObserver(imgDecoderObserver)::OnStartRequest");
}
virtual void OnStartContainer()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::OnStartContainer");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnStartContainer callback before we've created our image");
{
nsRefPtr<Image> image = mTracker->GetImage();
mTracker->RecordStartContainer(image);
}
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStartContainer(iter.GetNext());
}
}
virtual void OnStartFrame()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::OnStartFrame");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnStartFrame callback before we've created our image");
mTracker->RecordStartFrame();
// This is not observed below the imgStatusTracker level, so we don't need
// to SendStartFrame.
}
virtual void FrameChanged(const nsIntRect* dirtyRect)
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::FrameChanged");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"FrameChanged callback before we've created our image");
mTracker->RecordFrameChanged(dirtyRect);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendFrameChanged(iter.GetNext(), dirtyRect);
}
}
virtual void OnStopFrame()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::OnStopFrame");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnStopFrame callback before we've created our image");
mTracker->RecordStopFrame();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopFrame(iter.GetNext());
}
mTracker->MaybeUnblockOnload();
}
virtual void OnStopDecode(nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTrackerNotifyingObserver::OnStopDecode");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnStopDecode callback before we've created our image");
bool preexistingError = mTracker->GetImageStatus() == imgIRequest::STATUS_ERROR;
mTracker->RecordStopDecode(aStatus);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopDecode(iter.GetNext(), aStatus);
}
// This is really hacky. We need to handle the case where we start decoding,
// block onload, but then hit an error before we get to our first frame.
mTracker->MaybeUnblockOnload();
if (NS_FAILED(aStatus) && !preexistingError) {
mTracker->FireFailureNotification();
}
}
virtual void OnStopRequest(bool aLastPart, nsresult aStatus)
{
NS_NOTREACHED("imgStatusTrackerNotifyingObserver(imgDecoderObserver)::OnStopRequest");
}
virtual void OnDiscard()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnDiscard callback before we've created our image");
mTracker->RecordDiscard();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendDiscard(iter.GetNext());
}
}
virtual void OnUnlockedDraw()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnUnlockedDraw callback before we've created our image");
mTracker->RecordUnlockedDraw();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendUnlockedDraw(iter.GetNext());
}
}
virtual void OnImageIsAnimated()
{
MOZ_ASSERT(NS_IsMainThread(),
"Use imgStatusTracker::mConsumers on main thread only");
NS_ABORT_IF_FALSE(mTracker->HasImage(),
"OnImageIsAnimated callback before we've created our image");
mTracker->RecordImageIsAnimated();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendImageIsAnimated(iter.GetNext());
}
}
virtual void OnError()
{
mTracker->RecordError();
}
private:
nsRefPtr<imgStatusTracker> mTracker;
};
class imgStatusTrackerObserver : public imgDecoderObserver
{
public:
@ -696,9 +499,11 @@ imgStatusTracker::SyncNotifyDifference(const ImageStatusDiff& diff)
LOG_SCOPE(GetImgLog(), "imgStatusTracker::SyncNotifyDifference");
nsIntRect invalidRect = mInvalidRect.Union(diff.invalidRect);
mInvalidRect.SetEmpty();
SyncNotifyState(mConsumers, !!mImage, diff.diffState, invalidRect, mHadLastPart);
mInvalidRect.SetEmpty();
if (diff.unblockedOnload) {
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
while (iter.HasMore()) {

View File

@ -13,7 +13,6 @@ class imgRequestProxy;
class imgStatusNotifyRunnable;
class imgRequestNotifyRunnable;
class imgStatusTrackerObserver;
class imgStatusTrackerNotifyingObserver;
class nsIRunnable;
#include "mozilla/RefPtr.h"
@ -299,7 +298,6 @@ private:
friend class imgStatusNotifyRunnable;
friend class imgRequestNotifyRunnable;
friend class imgStatusTrackerObserver;
friend class imgStatusTrackerNotifyingObserver;
friend class imgStatusTrackerInit;
imgStatusTracker(const imgStatusTracker& aOther);

View File

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "JavaScriptShared.h"
#include "mozilla/dom/BindingUtils.h"
#include "jsfriendapi.h"
#include "xpcprivate.h"
@ -57,20 +58,30 @@ ObjectStore::remove(ObjectId id)
}
ObjectIdCache::ObjectIdCache()
: table_(SystemAllocPolicy())
: table_(nullptr)
{
}
ObjectIdCache::~ObjectIdCache()
{
if (table_) {
dom::AddForDeferredFinalization<ObjectIdTable, nsAutoPtr>(table_);
table_ = nullptr;
}
}
bool
ObjectIdCache::init()
{
return table_.init(32);
MOZ_ASSERT(!table_);
table_ = new ObjectIdTable(SystemAllocPolicy());
return table_ && table_->init(32);
}
void
ObjectIdCache::trace(JSTracer *trc)
{
for (ObjectIdTable::Range r(table_.all()); !r.empty(); r.popFront()) {
for (ObjectIdTable::Range r(table_->all()); !r.empty(); r.popFront()) {
JSObject *obj = r.front().key;
JS_CallObjectTracer(trc, &obj, "ipc-id");
MOZ_ASSERT(obj == r.front().key);
@ -80,7 +91,7 @@ ObjectIdCache::trace(JSTracer *trc)
ObjectId
ObjectIdCache::find(JSObject *obj)
{
ObjectIdTable::Ptr p = table_.lookup(obj);
ObjectIdTable::Ptr p = table_->lookup(obj);
if (!p)
return 0;
return p->value;
@ -89,9 +100,9 @@ ObjectIdCache::find(JSObject *obj)
bool
ObjectIdCache::add(JSContext *cx, JSObject *obj, ObjectId id)
{
if (!table_.put(obj, id))
if (!table_->put(obj, id))
return false;
JS_StoreObjectPostBarrierCallback(cx, keyMarkCallback, obj, this);
JS_StoreObjectPostBarrierCallback(cx, keyMarkCallback, obj, table_);
return true;
}
@ -100,18 +111,18 @@ ObjectIdCache::add(JSContext *cx, JSObject *obj, ObjectId id)
* been moved.
*/
/* static */ void
ObjectIdCache::keyMarkCallback(JSTracer *trc, void *k, void *d) {
JSObject *key = static_cast<JSObject*>(k);
ObjectIdCache* self = static_cast<ObjectIdCache*>(d);
ObjectIdCache::keyMarkCallback(JSTracer *trc, void *keyArg, void *dataArg) {
JSObject *key = static_cast<JSObject*>(keyArg);
ObjectIdTable* table = static_cast<ObjectIdTable*>(dataArg);
JSObject *prior = key;
JS_CallObjectTracer(trc, &key, "ObjectIdCache::table_ key");
self->table_.rekeyIfMoved(prior, key);
table->rekeyIfMoved(prior, key);
}
void
ObjectIdCache::remove(JSObject *obj)
{
table_.remove(obj);
table_->remove(obj);
}
bool

View File

@ -65,6 +65,7 @@ class ObjectIdCache
public:
ObjectIdCache();
~ObjectIdCache();
bool init();
void trace(JSTracer *trc);
@ -76,7 +77,7 @@ class ObjectIdCache
private:
static void keyMarkCallback(JSTracer *trc, void *key, void *data);
ObjectIdTable table_;
ObjectIdTable *table_;
};
class JavaScriptShared

View File

@ -222,6 +222,11 @@ class Heap : public js::HeapBase<T>
return *this;
}
Heap<T> &operator=(const Heap<T>& other) {
set(other.get());
return *this;
}
void set(T newPtr) {
JS_ASSERT(!js::GCMethods<T>::poisoned(newPtr));
if (js::GCMethods<T>::needsPostBarrier(newPtr)) {
@ -348,6 +353,11 @@ class TenuredHeap : public js::HeapBase<T>
return *this;
}
TenuredHeap<T> &operator=(const TenuredHeap<T>& other) {
bits = other.bits;
return *this;
}
/*
* Set the pointer to a value which will cause a crash if it is
* dereferenced.
@ -576,6 +586,9 @@ class InternalHandle<T*>
: holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
{}
InternalHandle(const InternalHandle<T*>& other)
: holder(other.holder), offset(other.offset) {}
T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
const T &operator*() const { return *get(); }
@ -599,6 +612,8 @@ class InternalHandle<T*>
: holder(reinterpret_cast<void * const *>(&js::NullPtr::constNullValue)),
offset(uintptr_t(field))
{}
void operator=(InternalHandle<T*> other) MOZ_DELETE;
};
/*
@ -913,10 +928,16 @@ class FakeRooted : public RootedBase<T>
T &get() { return ptr; }
const T &get() const { return ptr; }
T &operator=(T value) {
FakeRooted<T> &operator=(T value) {
JS_ASSERT(!GCMethods<T>::poisoned(value));
ptr = value;
return ptr;
return *this;
}
FakeRooted<T> &operator=(const FakeRooted<T> &other) {
JS_ASSERT(!GCMethods<T>::poisoned(other.ptr));
ptr = other.ptr;
return *this;
}
bool operator!=(const T &other) const { return ptr != other; }
@ -961,6 +982,8 @@ class FakeMutableHandle : public js::MutableHandleBase<T>
template <typename S>
void operator=(S v) MOZ_DELETE;
void operator=(const FakeMutableHandle<T>& other) MOZ_DELETE;
};
/*

View File

@ -238,7 +238,7 @@ ifeq ($(OS_ARCH),WINNT)
ICU_LIB_SUFFIX=d
endif
ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
cp -p intl/icu/lib/s$(libname)$(ICU_LIB_SUFFIX).lib intl/icu/lib/$(libname).lib;)
cp -p intl/icu/target/lib/s$(libname)$(ICU_LIB_SUFFIX).lib intl/icu/target/lib/$(libname).lib;)
endif
ifdef .PYMAKE
@ -254,11 +254,17 @@ endif
# - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
buildicu:
# ICU's build system is full of races, so force non-parallel build.
+$(ICU_MAKE) -j1 -C intl/icu STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R'
ifdef CROSS_COMPILE
+$(ICU_MAKE) -j1 -C intl/icu/host STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R -C'
endif
+$(ICU_MAKE) -j1 -C intl/icu/target STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R'
$(ICU_LIB_RENAME)
distclean clean::
$(call SUBMAKE,$@,intl/icu)
ifdef CROSS_COMPILE
$(call SUBMAKE,$@,intl/icu/host)
endif
$(call SUBMAKE,$@,intl/icu/target)
endif
endif

View File

@ -175,7 +175,7 @@ TraceLogging::log(Type type, const char* text /* = nullptr */, unsigned int numb
void
TraceLogging::log(Type type, const JS::ReadOnlyCompileOptions &options)
{
this->log(type, options.filename, options.lineno);
this->log(type, options.filename(), options.lineno);
}
void

1
js/src/aclocal.m4 vendored
View File

@ -11,6 +11,7 @@ builtin(include, build/autoconf/ccache.m4)dnl
builtin(include, build/autoconf/wrapper.m4)dnl
builtin(include, build/autoconf/pkg.m4)dnl
builtin(include, build/autoconf/nspr.m4)dnl
builtin(include, build/autoconf/codeset.m4)dnl
builtin(include, build/autoconf/altoptions.m4)dnl
builtin(include, build/autoconf/mozprog.m4)dnl
builtin(include, build/autoconf/mozheader.m4)dnl

View File

@ -0,0 +1,24 @@
# codeset.m4 serial AM1 (gettext-0.10.40)
dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
dnl Public License, this file may be distributed as part of a program
dnl that contains a configuration script generated by Autoconf, under
dnl the same distribution terms as the rest of that program.
dnl From Bruno Haible.
AC_DEFUN([AM_LANGINFO_CODESET],
[
AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
[AC_TRY_LINK([#include <langinfo.h>],
[char* cs = nl_langinfo(CODESET);],
am_cv_langinfo_codeset=yes,
am_cv_langinfo_codeset=no)
])
if test $am_cv_langinfo_codeset = yes; then
AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
[Define if you have <langinfo.h> and nl_langinfo(CODESET).])
HAVE_LANGINFO_CODESET=1
fi
])

View File

@ -1329,7 +1329,11 @@ Neuter(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
return JS_NeuterArrayBuffer(cx, obj);
if (!JS_NeuterArrayBuffer(cx, obj))
return false;
args.rval().setUndefined();
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = {

View File

@ -2570,6 +2570,8 @@ dnl AC_CHECK_LIB(bind, res_ninit, AC_DEFINE(HAVE_RES_NINIT),
dnl AC_CHECK_LIB(resolv, res_ninit, AC_DEFINE(HAVE_RES_NINIT)))
fi
AM_LANGINFO_CODESET
AC_LANG_C
dnl **********************
@ -4193,7 +4195,7 @@ if test -n "$ENABLE_INTL_API"; then
*)
AC_MSG_ERROR([ECMAScript Internationalization API is not yet supported on this platform])
esac
MOZ_ICU_LIBS='$(call EXPAND_LIBNAME_PATH,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/lib)'
MOZ_ICU_LIBS='$(call EXPAND_LIBNAME_PATH,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib)'
fi
fi
@ -4223,33 +4225,94 @@ if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then
ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_REGULAR_EXPRESSIONS"
ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_BREAK_ITERATION"
ICU_CROSS_BUILD_OPT=""
ICU_SRCDIR=""
# Set OS dependent options for ICU
case "$OS_TARGET" in
Darwin)
ICU_TARGET=MacOSX
;;
Linux)
ICU_TARGET=Linux
;;
WINNT)
ICU_TARGET=MSYS/MSVC
ICU_SRCDIR="--srcdir=$(cd $srcdir/../../intl/icu/source; pwd -W)"
;;
DragonFly|FreeBSD|NetBSD|OpenBSD)
ICU_TARGET=BSD
;;
esac
if test "$HOST_OS_ARCH" = "WINNT"; then
ICU_SRCDIR="--srcdir=$(cd $srcdir/../../intl/icu/source; pwd -W)"
fi
if test "$CROSS_COMPILE"; then
# Building host tools. It is necessary to build target binary.
case "$HOST_OS_ARCH" in
Darwin)
ICU_TARGET=MacOSX
;;
Linux)
ICU_TARGET=Linux
;;
WINNT)
ICU_TARGET=MSYS/MSVC
;;
*bsd*|dragonfly*)
ICU_TARGET=BSD
;;
esac
# Remove _DEPEND_CFLAGS from HOST_FLAGS to avoid configure error
HOST_ICU_CFLAGS="$HOST_CFLAGS"
HOST_ICU_CXXFLAGS="$HOST_CXXFLAGS"
HOST_ICU_CFLAGS=`echo $HOST_ICU_CFLAGS | sed "s|$_DEPEND_CFLAGS||g"`
HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CFXXLAGS | sed "s|$_DEPEND_CFLAGS||g"`
# ICU requires RTTI
if test "$GNU_CC"; then
HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CXXFLAGS | sed 's|-fno-rtti|-frtti|g'`
elif test "$_MSC_VER"; then
HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CXXFLAGS | sed 's|-GR-|-GR|g'`
fi
HOST_ICU_BUILD_OPTS=""
if test -n "$MOZ_DEBUG"; then
HOST_ICU_BUILD_OPTS="$HOST_ICU_BUILD_OPTS --enable-debug"
fi
abs_srcdir=`(cd $srcdir; pwd)`
mkdir -p $_objdir/intl/icu/host
(cd $_objdir/intl/icu/host
MOZ_SUBCONFIGURE_WRAP([.],[
CC="$HOST_CC" CXX="$HOST_CXX" LD="$HOST_LD" \
CFLAGS="$HOST_ICU_CFLAGS $HOST_OPTIMIZE_FLAGS" \
CPPFLAGS="$ICU_CPPFLAGS" \
CXXFLAGS="$HOST_ICU_CXXFLAGS $HOST_OPTIMZIE_FLAGS" \
$SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \
$HOST_ICU_BUILD_OPTS \
$ICU_TARGET \
dnl Shell quoting is fun.
${ICU_SRCDIR+"$ICU_SRCDIR"} \
--enable-static --disable-shared \
--enable-extras=no --enable-icuio=no --enable-layout=no \
--enable-tests=no --enable-samples=no || exit 1
])
) || exit 1
# generate config/icucross.mk
$GMAKE -C $_objdir/intl/icu/host/ config/icucross.mk
# --with-cross-build requires absolute path
ICU_HOST_PATH=`cd $_objdir/intl/icu/host && pwd`
ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH"
fi
# To reduce library size, use static linking
ICU_LINK_OPTS="--enable-static --disable-shared"
# Force the ICU static libraries to be position independent code
ICU_CFLAGS="$DSO_PIC_CFLAGS"
ICU_CXXFLAGS="$DSO_PIC_CFLAGS"
ICU_CFLAGS="$DSO_PIC_CFLAGS $CFLAGS"
ICU_CXXFLAGS="$DSO_PIC_CFLAGS $CXXFLAGS"
ICU_BUILD_OPTS=""
if test -n "$MOZ_DEBUG"; then
ICU_BUILD_OPTS="$ICU_BUILD_OPTS --enable-debug"
if test -n "$MOZ_DEBUG" -o "MOZ_DEBUG_SYMBOLS"; then
ICU_CFLAGS="$ICU_CFLAGS $MOZ_DEBUG_FLAGS"
ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_DEBUG_FLAGS"
ICU_LDFLAGS="$MOZ_DEBUG_LDFLAGS"
if test -z "$MOZ_DEBUG"; then
# To generate debug symbols, it requires MOZ_DEBUG_FLAGS.
# But, not debug build.
ICU_CFLAGS="$ICU_CFLAGS -UDEBUG -DNDEBUG"
ICU_CXXFLAGS="$ICU_CXXFLAGS -UDEBUG -DNDEBUG"
else
ICU_BUILD_OPTS="$ICU_BUILD_OPTS --enable-debug"
fi
fi
if test -z "$MOZ_OPTIMIZE"; then
ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release"
@ -4258,21 +4321,43 @@ if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then
ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_OPTIMIZE_FLAGS"
fi
abs_srcdir=`(cd $srcdir; pwd)`
mkdir -p $_objdir/intl/icu
(cd $_objdir/intl/icu
if test "$am_cv_langinfo_codeset" = "no"; then
# ex. Android
ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_HAVE_NL_LANGINFO_CODESET=0"
fi
# ICU requires RTTI
if test "$GNU_CC"; then
ICU_CXXFLAGS=`echo $ICU_CXXFLAGS | sed 's|-fno-rtti|-frtti|g'`
else
if test "$_MSC_VER"; then
ICU_CXXFLAGS=`echo $ICU_CXXFLAGS | sed 's|-GR-|-GR|g'`
fi
fi
# We cannot use AC_OUTPUT_SUBDIRS since ICU tree is out of spidermonkey.
# When using AC_OUTPUT_SUBDIRS, objdir of ICU is out of objdir
# due to relative path.
# If building ICU moves into root of mozilla tree, we can use
# AC_OUTPUT_SUBDIR instead.
mkdir -p $_objdir/intl/icu/target
(cd $_objdir/intl/icu/target
MOZ_SUBCONFIGURE_WRAP([.],[
CC="$CC" CXX="$CXX" \
CFLAGS="$ICU_CFLAGS" CPPFLAGS="$ICU_CPPFLAGS" CXXFLAGS="$ICU_CXXFLAGS" \
$SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \
$ICU_BUILD_OPTS \
$ICU_TARGET \
$ICU_LINK_OPTS \
dnl Shell quoting is fun.
${ICU_SRCDIR+"$ICU_SRCDIR"} \
--enable-extras=no --enable-icuio=no --enable-layout=no \
--enable-tests=no --enable-samples=no || exit 1
])
AR="$AR" CC="$CC" CXX="$CXX" LD="$LD" \
ARFLAGS="$ARFLAGS" \
CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS" \
CFLAGS="$ICU_CFLAGS" \
CXXFLAGS="$ICU_CXXFLAGS" \
LDFLAGS="$ICU_LDFLAGS $LDFLAGS" \
$SHELL $_topsrcdir/../../intl/icu/source/configure \
$ICU_BUILD_OPTS \
$ICU_CROSS_BUILD_OPT \
$ICU_LINK_OPTS \
${ICU_SRCDIR+"$ICU_SRCDIR"} \
--build=$build --host=$target \
--disable-extras --disable-icuio --disable-layout \
--disable-tests --disable-samples || exit 1
])
) || exit 1
fi

View File

@ -509,8 +509,6 @@ static bool
FlushPops(ExclusiveContext *cx, BytecodeEmitter *bce, int *npops)
{
JS_ASSERT(*npops != 0);
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
EMIT_UINT16_IMM_OP(JSOP_POPN, *npops);
*npops = 0;
return true;
@ -519,8 +517,6 @@ FlushPops(ExclusiveContext *cx, BytecodeEmitter *bce, int *npops)
static bool
PopIterator(ExclusiveContext *cx, BytecodeEmitter *bce)
{
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (Emit1(cx, bce, JSOP_ENDITER) < 0)
return false;
return true;
@ -547,8 +543,6 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
switch (stmt->type) {
case STMT_FINALLY:
FLUSH_POPS();
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (EmitBackPatchOp(cx, bce, &stmt->gosubs()) < 0)
return false;
break;
@ -556,8 +550,6 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
case STMT_WITH:
/* There's a With object on the stack that we need to pop. */
FLUSH_POPS();
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (Emit1(cx, bce, JSOP_LEAVEWITH) < 0)
return false;
break;
@ -596,8 +588,6 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
stmt = stmt->down;
if (stmt == toStmt)
break;
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (Emit1(cx, bce, JSOP_LEAVEFORLETIN) < 0)
return false;
if (stmt->type == STMT_FOR_OF_LOOP) {
@ -607,13 +597,9 @@ EmitNonLocalJumpFixup(ExclusiveContext *cx, BytecodeEmitter *bce, StmtInfoBCE *t
if (!PopIterator(cx, bce))
return false;
}
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
EMIT_UINT16_IMM_OP(JSOP_POPN, popCount);
} else {
/* There is a Block object with locals on the stack to pop. */
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, blockObjCount);
}
}
@ -2530,7 +2516,7 @@ EmitSwitch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* If we didn't have an explicit default (which could fall in between
* cases, preventing us from fusing this SetSrcNoteOffset with the call
* in the loop above), link the last case to the implicit default for
* the decompiler.
* the benefit of IonBuilder.
*/
if (!hasDefault &&
caseNoteIndex >= 0 &&
@ -2658,7 +2644,7 @@ bool
frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *body)
{
/*
* The decompiler has assumptions about what may occur immediately after
* IonBuilder has assumptions about what may occur immediately after
* script->main (e.g., in the case of destructuring params). Thus, put the
* following ops into the range [script->code, script->main). Note:
* execution starts from script->code, so this has no semantic effect.
@ -3008,12 +2994,6 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
JS_ASSERT(pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT));
#endif
if (pn->pn_count == 0) {
/* Emit a DUP;POP sequence for the decompiler. */
if (Emit1(cx, bce, JSOP_DUP) < 0 || Emit1(cx, bce, JSOP_POP) < 0)
return false;
}
index = 0;
for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
/* Duplicate the value being destructured to use as a reference base. */
@ -3081,13 +3061,13 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
if (emitOption == PushInitialValues) {
/*
* After '[x,y]' in 'let ([[x,y], z] = o)', the stack is
* | to-be-decompiled-value | x | y |
* | to-be-destructured-value | x | y |
* The goal is:
* | x | y | z |
* so emit a pick to produce the intermediate state
* | x | y | to-be-decompiled-value |
* | x | y | to-be-destructured-value |
* before destructuring z. This gives the loop invariant that
* the to-be-compiled-value is always on top of the stack.
* the to-be-destructured-value is always on top of the stack.
*/
JS_ASSERT((bce->stackDepth - bce->stackDepth) >= -1);
unsigned pickDistance = (unsigned)((bce->stackDepth + 1) - depthBefore);
@ -3107,7 +3087,7 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
if (emitOption == PushInitialValues) {
/*
* Per the above loop invariant, to-be-decompiled-value is at the top
* Per the above loop invariant, to-be-destructured-value is at the top
* of the stack. To achieve the post-condition, pop it.
*/
if (Emit1(cx, bce, JSOP_POP) < 0)
@ -3848,14 +3828,7 @@ EmitCatch(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
/* Emit the catch body. */
if (!EmitTree(cx, bce, pn->pn_kid3))
return false;
/*
* Annotate the JSOP_LEAVEBLOCK that will be emitted as we unwind via
* our PNK_LEXICALSCOPE parent, so the decompiler knows to pop.
*/
return NewSrcNote(cx, bce, SRC_CATCH) >= 0;
return EmitTree(cx, bce, pn->pn_kid3);
}
/*
@ -3900,8 +3873,6 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
/* GOSUB to finally, if present. */
if (pn->pn_kid3) {
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (EmitBackPatchOp(cx, bce, &stmtInfo.gosubs()) < 0)
return false;
}
@ -3911,8 +3882,6 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
/* Emit (hidden) jump over catch and/or finally. */
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
ptrdiff_t catchJump = -1;
if (EmitBackPatchOp(cx, bce, &catchJump) < 0)
return false;
@ -3964,15 +3933,9 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
/*
* Move exception back to cx->exception to prepare for
* the next catch. We hide [throwing] from the decompiler
* since it compensates for the hidden JSOP_DUP at the
* start of the previous guarded catch.
* the next catch.
*/
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0 ||
Emit1(cx, bce, JSOP_THROWING) < 0) {
return false;
}
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
if (Emit1(cx, bce, JSOP_THROWING) < 0)
return false;
EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, count);
JS_ASSERT(bce->stackDepth == depth);
@ -3999,8 +3962,6 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* Jump over the remaining catch blocks. This will get fixed
* up to jump to after catch/finally.
*/
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (EmitBackPatchOp(cx, bce, &catchJump) < 0)
return false;
@ -4029,7 +3990,7 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* Rethrow the exception, delegating executing of finally if any
* to the exception handler.
*/
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0 || Emit1(cx, bce, JSOP_THROW) < 0)
if (Emit1(cx, bce, JSOP_THROW) < 0)
return false;
}
@ -4558,9 +4519,7 @@ EmitForIn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t t
/*
* Emit code to get the next enumeration value and assign it to the
* left hand side. The JSOP_POP after this assignment is annotated
* so that the decompiler can distinguish 'for (x in y)' from
* 'for (var x in y)'.
* left hand side.
*/
if (Emit1(cx, bce, JSOP_ITERNEXT) < 0)
return false;
@ -4634,7 +4593,8 @@ EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff
JSOp op = JSOP_POP;
ParseNode *pn3 = forHead->pn_kid1;
if (!pn3) {
/* No initializer: emit an annotated nop for the decompiler. */
// No initializer, but emit a nop so that there's somewhere to put the
// SRC_FOR annotation that IonBuilder will look for.
op = JSOP_NOP;
} else {
bce->emittingForInit = true;
@ -4655,7 +4615,7 @@ EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff
* Check whether a destructuring-initialized var decl
* was optimized to a group assignment. If so, we do
* not need to emit a pop below, so switch to a nop,
* just for the decompiler.
* just for IonBuilder.
*/
JS_ASSERT(pn3->isArity(PN_LIST) || pn3->isArity(PN_BINARY));
if (pn3->pn_xflags & PNX_GROUPINIT)
@ -4724,7 +4684,7 @@ EmitNormalFor(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff
if (op == JSOP_POP && !EmitTree(cx, bce, pn3))
return false;
/* Always emit the POP or NOP, to help the decompiler. */
/* Always emit the POP or NOP to help IonBuilder. */
if (Emit1(cx, bce, op) < 0)
return false;
@ -4929,7 +4889,7 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
static bool
EmitDo(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
/* Emit an annotated nop so we know to decompile a 'do' keyword. */
/* Emit an annotated nop so IonBuilder can recognize the 'do' loop. */
ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_WHILE);
if (noteIndex < 0 || Emit1(cx, bce, JSOP_NOP) < 0)
return false;
@ -4963,11 +4923,6 @@ EmitDo(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (!EmitTree(cx, bce, pn->pn_right))
return false;
/*
* Since we use JSOP_IFNE for other purposes as well as for do-while
* loops, we must store 1 + (beq - top) in the SRC_WHILE note offset,
* and the decompiler must get that delta and decompile recursively.
*/
ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
if (beq < 0)
return false;
@ -4976,6 +4931,9 @@ EmitDo(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return false;
/*
* Update the annotations with the update and back edge positions, for
* IonBuilder.
*
* Be careful: We must set noteIndex2 before noteIndex in case the noteIndex
* note gets bigger.
*/
@ -5179,8 +5137,6 @@ EmitYieldStar(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *iter)
// Try epilogue.
if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, bce->offset() - tryStart + JSOP_TRY_LENGTH))
return false;
if (NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
ptrdiff_t subsequentSend = -1;
if (EmitBackPatchOp(cx, bce, &subsequentSend) < 0) // goto subsequentSend
return false;
@ -6328,8 +6284,6 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (!EmitFinishIteratorResult(cx, bce, false))
return false;
}
if (pn->pn_hidden && NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
return false;
if (Emit1(cx, bce, JSOP_YIELD) < 0)
return false;
break;

View File

@ -420,7 +420,6 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode *opn)
case PN_UNARY:
NULLCHECK(pn->pn_kid = cloneParseTree(opn->pn_kid));
pn->pn_hidden = opn->pn_hidden;
break;
case PN_NAME:

View File

@ -523,8 +523,7 @@ class ParseNode
} binary;
struct { /* one kid if unary */
ParseNode *kid;
bool hidden; /* hidden genexp-induced JSOP_YIELD
or directive prologue member (as
bool prologue; /* directive prologue member (as
pn_prologue) */
} unary;
struct { /* name, labeled statement, etc. */
@ -575,8 +574,7 @@ class ParseNode
#define pn_pval pn_u.binary.pval
#define pn_iflags pn_u.binary.iflags
#define pn_kid pn_u.unary.kid
#define pn_hidden pn_u.unary.hidden
#define pn_prologue pn_u.unary.hidden
#define pn_prologue pn_u.unary.prologue
#define pn_atom pn_u.name.atom
#define pn_objbox pn_u.name.objbox
#define pn_expr pn_u.name.expr

View File

@ -6302,7 +6302,6 @@ Parser<FullParseHandler>::generatorExpr(ParseNode *kid)
pn->setInParens(true);
pn->pn_pos = kid->pn_pos;
pn->pn_kid = kid;
pn->pn_hidden = true;
/* Make a new node for the desugared generator function. */
ParseNode *genfn = CodeNode::create(PNK_FUNCTION, &handler);

View File

@ -59,14 +59,14 @@ namespace js {
M(SRC_NEXTCASE, "nextcase", 1) /* Distance forward from one CASE in a CONDSWITCH to \
the next. */ \
M(SRC_ASSIGNOP, "assignop", 0) /* += or another assign-op follows. */ \
M(SRC_HIDDEN, "hidden", 0) /* Opcode shouldn't be decompiled. */ \
M(SRC_CATCH, "catch", 0) /* Catch block has guard. */ \
M(SRC_TRY, "try", 1) /* JSOP_TRY, offset points to goto at the end of the \
try block. */ \
/* All notes below here are "gettable". See SN_IS_GETTABLE below. */ \
M(SRC_COLSPAN, "colspan", 1) /* Number of columns this opcode spans. */ \
M(SRC_NEWLINE, "newline", 0) /* Bytecode follows a source newline. */ \
M(SRC_SETLINE, "setline", 1) /* A file-absolute source line number note. */ \
M(SRC_UNUSED20, "unused20", 0) /* Unused. */ \
M(SRC_UNUSED21, "unused21", 0) /* Unused. */ \
M(SRC_UNUSED22, "unused22", 0) /* Unused. */ \
M(SRC_UNUSED23, "unused23", 0) /* Unused. */ \
M(SRC_XDELTA, "xdelta", 0) /* 24-31 are for extended delta notes. */

View File

@ -0,0 +1,6 @@
function x() {}
ParallelArray(3385, function(y) {
Object.defineProperty([], 8, {
e: (y ? x : Math.fround(1))
})
})

View File

@ -19,6 +19,41 @@ using namespace js::jit;
using mozilla::Array;
namespace js {
namespace jit {
class LoopAliasInfo : public TempObject
{
private:
LoopAliasInfo *outer_;
MBasicBlock *loopHeader_;
MDefinitionVector invariantLoads_;
public:
LoopAliasInfo(TempAllocator &alloc, LoopAliasInfo *outer, MBasicBlock *loopHeader)
: outer_(outer), loopHeader_(loopHeader), invariantLoads_(alloc)
{ }
MBasicBlock *loopHeader() const {
return loopHeader_;
}
LoopAliasInfo *outer() const {
return outer_;
}
bool addInvariantLoad(MDefinition *ins) {
return invariantLoads_.append(ins);
}
const MDefinitionVector& invariantLoads() const {
return invariantLoads_;
}
MDefinition *firstInstruction() const {
return *loopHeader_->begin();
}
};
} // namespace jit
} // namespace js
namespace {
// Iterates over the flags in an AliasSet.
@ -128,12 +163,15 @@ IonSpewAliasInfo(const char *pre, MDefinition *ins, const char *post)
bool
AliasAnalysis::analyze()
{
Array<MDefinitionVector, AliasSet::NumCategories> stores;
Vector<MDefinitionVector, AliasSet::NumCategories, IonAllocPolicy> stores(alloc());
// Initialize to the first instruction.
MDefinition *firstIns = *graph_.begin()->begin();
for (unsigned i=0; i < AliasSet::NumCategories; i++) {
if (!stores[i].append(firstIns))
for (unsigned i = 0; i < AliasSet::NumCategories; i++) {
MDefinitionVector defs(alloc());
if (!defs.append(firstIns))
return false;
if (!stores.append(OldMove(defs)))
return false;
}
@ -148,7 +186,7 @@ AliasAnalysis::analyze()
if (block->isLoopHeader()) {
IonSpew(IonSpew_Alias, "Processing loop header %d", block->id());
loop_ = new(graph_.alloc()) LoopAliasInfo(loop_, *block);
loop_ = new(alloc()) LoopAliasInfo(alloc(), loop_, *block);
}
for (MDefinitionIterator def(*block); def; def++) {
@ -208,7 +246,7 @@ AliasAnalysis::analyze()
LoopAliasInfo *outerLoop = loop_->outer();
MInstruction *firstLoopIns = *loop_->loopHeader()->begin();
const InstructionVector &invariant = loop_->invariantLoads();
const MDefinitionVector &invariant = loop_->invariantLoads();
for (unsigned i = 0; i < invariant.length(); i++) {
MDefinition *ins = invariant[i];

View File

@ -13,45 +13,19 @@
namespace js {
namespace jit {
class LoopAliasInfo;
class MIRGraph;
typedef Vector<MDefinition *, 4, IonAllocPolicy> InstructionVector;
class LoopAliasInfo : public TempObject
{
private:
LoopAliasInfo *outer_;
MBasicBlock *loopHeader_;
InstructionVector invariantLoads_;
public:
LoopAliasInfo(LoopAliasInfo *outer, MBasicBlock *loopHeader)
: outer_(outer), loopHeader_(loopHeader)
{ }
MBasicBlock *loopHeader() const {
return loopHeader_;
}
LoopAliasInfo *outer() const {
return outer_;
}
bool addInvariantLoad(MDefinition *ins) {
return invariantLoads_.append(ins);
}
const InstructionVector& invariantLoads() const {
return invariantLoads_;
}
MDefinition *firstInstruction() const {
return *loopHeader_->begin();
}
};
class AliasAnalysis
{
MIRGenerator *mir;
MIRGraph &graph_;
LoopAliasInfo *loop_;
TempAllocator &alloc() const {
return graph_.alloc();
}
public:
AliasAnalysis(MIRGenerator *mir, MIRGraph &graph);
bool analyze();

View File

@ -46,7 +46,7 @@ BacktrackingAllocator::init()
// crapshoot, so just mark the bodies of inner loops as hot and everything
// else as cold.
LiveInterval *hotcodeInterval = new(alloc()) LiveInterval(0);
LiveInterval *hotcodeInterval = LiveInterval::New(alloc(), 0);
LBlock *backedge = nullptr;
for (size_t i = 0; i < graph.numBlocks(); i++) {
@ -227,7 +227,7 @@ BacktrackingAllocator::tryGroupRegisters(uint32_t vreg0, uint32_t vreg1)
if (LifetimesOverlap(reg0, reg1))
return true;
VirtualRegisterGroup *group = new(alloc()) VirtualRegisterGroup();
VirtualRegisterGroup *group = new(alloc()) VirtualRegisterGroup(alloc());
if (!group->registers.append(vreg0) || !group->registers.append(vreg1))
return false;
@ -299,7 +299,7 @@ BacktrackingAllocator::tryGroupReusedRegister(uint32_t def, uint32_t use)
}
}
LiveInterval *preInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
LiveInterval *preInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
for (size_t i = 0; i < interval->numRanges(); i++) {
const LiveInterval::Range *range = interval->getRange(i);
JS_ASSERT(range->from <= inputOf(reg.ins()));
@ -309,7 +309,7 @@ BacktrackingAllocator::tryGroupReusedRegister(uint32_t def, uint32_t use)
return false;
}
LiveInterval *postInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
LiveInterval *postInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
if (!postInterval->addRange(inputOf(reg.ins()), interval->end()))
return false;
@ -954,7 +954,7 @@ BacktrackingAllocator::resolveControlFlow()
LiveInterval *from = vregs[input].intervalFor(outputOf(predecessor->lastId()));
JS_ASSERT(from);
LMoveGroup *moves = predecessor->getExitMoveGroup();
LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
if (!addMove(moves, from, to))
return false;
}
@ -980,11 +980,11 @@ BacktrackingAllocator::resolveControlFlow()
if (mSuccessor->numPredecessors() > 1) {
JS_ASSERT(predecessor->mir()->numSuccessors() == 1);
LMoveGroup *moves = predecessor->getExitMoveGroup();
LMoveGroup *moves = predecessor->getExitMoveGroup(alloc());
if (!addMove(moves, from, to))
return false;
} else {
LMoveGroup *moves = successor->getEntryMoveGroup();
LMoveGroup *moves = successor->getEntryMoveGroup(alloc());
if (!addMove(moves, from, to))
return false;
}
@ -1322,7 +1322,7 @@ BacktrackingAllocator::addLiveInterval(LiveIntervalVector &intervals, uint32_t v
LiveInterval *spillInterval,
CodePosition from, CodePosition to)
{
LiveInterval *interval = new(alloc()) LiveInterval(vreg, 0);
LiveInterval *interval = LiveInterval::New(alloc(), vreg, 0);
interval->setSpillInterval(spillInterval);
return interval->addRange(from, to) && intervals.append(interval);
}
@ -1511,7 +1511,7 @@ BacktrackingAllocator::trySplitAcrossHotcode(LiveInterval *interval, bool *succe
if (!coldCode)
return true;
LiveInterval *hotInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
LiveInterval *hotInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
LiveInterval *preInterval = nullptr, *postInterval = nullptr;
// Accumulate the ranges of hot and cold code in the interval. Note that
@ -1527,14 +1527,14 @@ BacktrackingAllocator::trySplitAcrossHotcode(LiveInterval *interval, bool *succe
if (!coldPre.empty()) {
if (!preInterval)
preInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
preInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
if (!preInterval->addRange(coldPre.from, coldPre.to))
return false;
}
if (!coldPost.empty()) {
if (!postInterval)
postInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
postInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
if (!postInterval->addRange(coldPost.from, coldPost.to))
return false;
}
@ -1587,8 +1587,8 @@ BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, bool
return true;
}
LiveInterval *preInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
LiveInterval *postInterval = new(alloc()) LiveInterval(interval->vreg(), 0);
LiveInterval *preInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
LiveInterval *postInterval = LiveInterval::New(alloc(), interval->vreg(), 0);
for (size_t i = 0; i < interval->numRanges(); i++) {
const LiveInterval::Range *range = interval->getRange(i);
@ -1631,7 +1631,7 @@ BacktrackingAllocator::splitAtAllRegisterUses(LiveInterval *interval)
bool spillIntervalIsNew = false;
LiveInterval *spillInterval = interval->spillInterval();
if (!spillInterval) {
spillInterval = new(alloc()) LiveInterval(vreg, 0);
spillInterval = LiveInterval::New(alloc(), vreg, 0);
spillIntervalIsNew = true;
}
@ -1723,7 +1723,7 @@ BacktrackingAllocator::splitAcrossCalls(LiveInterval *interval)
bool spillIntervalIsNew = false;
LiveInterval *spillInterval = interval->spillInterval();
if (!spillInterval) {
spillInterval = new(alloc()) LiveInterval(vreg, 0);
spillInterval = LiveInterval::New(alloc(), vreg, 0);
spillIntervalIsNew = true;
for (size_t i = 0; i < interval->numRanges(); i++) {
@ -1738,7 +1738,7 @@ BacktrackingAllocator::splitAcrossCalls(LiveInterval *interval)
CodePosition lastRegisterUse;
if (spillStart != interval->start()) {
LiveInterval *newInterval = new(alloc()) LiveInterval(vreg, 0);
LiveInterval *newInterval = LiveInterval::New(alloc(), vreg, 0);
newInterval->setSpillInterval(spillInterval);
if (!newIntervals.append(newInterval))
return false;
@ -1779,7 +1779,7 @@ BacktrackingAllocator::splitAcrossCalls(LiveInterval *interval)
}
}
if (useNewInterval) {
LiveInterval *newInterval = new(alloc()) LiveInterval(vreg, 0);
LiveInterval *newInterval = LiveInterval::New(alloc(), vreg, 0);
newInterval->setSpillInterval(spillInterval);
if (!newIntervals.append(newInterval))
return false;

View File

@ -36,8 +36,8 @@ struct VirtualRegisterGroup : public TempObject
// Spill location to be shared by registers in the group.
LAllocation spill;
VirtualRegisterGroup()
: allocation(LUse(0, LUse::ANY)), spill(LUse(0, LUse::ANY))
VirtualRegisterGroup(TempAllocator &alloc)
: registers(alloc), allocation(LUse(0, LUse::ANY)), spill(LUse(0, LUse::ANY))
{}
uint32_t canonicalReg() {
@ -67,6 +67,9 @@ class BacktrackingVirtualRegister : public VirtualRegister
VirtualRegisterGroup *group_;
public:
BacktrackingVirtualRegister(TempAllocator &alloc)
: VirtualRegister(alloc)
{}
void setMustCopyInput() {
mustCopyInput_ = true;
}

View File

@ -24,8 +24,8 @@
using namespace js;
using namespace js::jit;
BaselineCompiler::BaselineCompiler(JSContext *cx, HandleScript script)
: BaselineCompilerSpecific(cx, script),
BaselineCompiler::BaselineCompiler(JSContext *cx, TempAllocator &alloc, HandleScript script)
: BaselineCompilerSpecific(cx, alloc, script),
modifiesArguments_(false)
{
}
@ -33,7 +33,7 @@ BaselineCompiler::BaselineCompiler(JSContext *cx, HandleScript script)
bool
BaselineCompiler::init()
{
if (!analysis_.init(cx->runtime()->gsnCache))
if (!analysis_.init(alloc_, cx->runtime()->gsnCache))
return false;
if (!labels_.init(script->length))

View File

@ -194,7 +194,7 @@ class BaselineCompiler : public BaselineCompilerSpecific
}
public:
BaselineCompiler(JSContext *cx, HandleScript script);
BaselineCompiler(JSContext *cx, TempAllocator &alloc, HandleScript script);
bool init();
MethodStatus compile();

View File

@ -226,7 +226,7 @@ jit::BaselineCompile(JSContext *cx, HandleScript script)
IonContext ictx(cx, temp);
BaselineCompiler compiler(cx, script);
BaselineCompiler compiler(cx, *temp, script);
if (!compiler.init())
return Method_Error;

View File

@ -13,9 +13,9 @@
using namespace js;
using namespace js::jit;
BytecodeAnalysis::BytecodeAnalysis(JSScript *script)
BytecodeAnalysis::BytecodeAnalysis(TempAllocator &alloc, JSScript *script)
: script_(script),
infos_(),
infos_(alloc),
usesScopeChain_(false),
hasTryFinally_(false),
hasSetArg_(false)
@ -40,7 +40,7 @@ struct CatchFinallyRange
};
bool
BytecodeAnalysis::init(GSNCache &gsn)
BytecodeAnalysis::init(TempAllocator &alloc, GSNCache &gsn)
{
if (!infos_.growByUninitialized(script_->length))
return false;
@ -51,7 +51,7 @@ BytecodeAnalysis::init(GSNCache &gsn)
mozilla::PodZero(infos_.begin(), infos_.length());
infos_[0].init(/*stackDepth=*/0);
Vector<CatchFinallyRange, 0, IonAllocPolicy> catchFinallyRanges;
Vector<CatchFinallyRange, 0, IonAllocPolicy> catchFinallyRanges(alloc);
for (jsbytecode *pc = script_->code; pc < end; pc += GetBytecodeLength(pc)) {
JSOp op = JSOp(*pc);

View File

@ -45,9 +45,9 @@ class BytecodeAnalysis
bool hasSetArg_;
public:
explicit BytecodeAnalysis(JSScript *script);
explicit BytecodeAnalysis(TempAllocator &alloc, JSScript *script);
bool init(GSNCache &gsn);
bool init(TempAllocator &alloc, GSNCache &gsn);
BytecodeInfo &info(jsbytecode *pc) {
JS_ASSERT(infos_[pc - script_->code].initialized);

View File

@ -5829,7 +5829,7 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints)
// List of possible scripts that this graph may call. Currently this is
// only tracked when compiling for parallel execution.
CallTargetVector callTargets;
CallTargetVector callTargets(alloc());
if (executionMode == ParallelExecution)
AddPossibleCallees(cx, graph.mir(), callTargets);

Some files were not shown because too many files have changed in this diff Show More