本文整理汇总了C++中AutoTArray类的典型用法代码示例。如果您正苦于以下问题:C++ AutoTArray类的具体用法?C++ AutoTArray怎么用?C++ AutoTArray使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AutoTArray类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: index
nsresult
gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
uint32_t aOffset,
uint32_t aLength,
CTRunRef aCTRun,
int32_t aStringOffset)
{
// The word has been bidi-wrapped; aStringOffset is the number
// of chars at the beginning of the CTLine that we should skip.
// aCTRun is a glyph run from the CoreText layout process.
int32_t direction = aShapedText->IsRightToLeft() ? -1 : 1;
int32_t numGlyphs = ::CTRunGetGlyphCount(aCTRun);
if (numGlyphs == 0) {
return NS_OK;
}
int32_t wordLength = aLength;
// character offsets get really confusing here, as we have to keep track of
// (a) the text in the actual textRun we're constructing
// (c) the string that was handed to CoreText, which contains the text of the font run
// plus directional-override padding
// (d) the CTRun currently being processed, which may be a sub-run of the CoreText line
// (but may extend beyond the actual font run into the bidi wrapping text).
// aStringOffset tells us how many initial characters of the line to ignore.
// get the source string range within the CTLine's text
CFRange stringRange = ::CTRunGetStringRange(aCTRun);
// skip the run if it is entirely outside the actual range of the font run
if (stringRange.location - aStringOffset + stringRange.length <= 0 ||
stringRange.location - aStringOffset >= wordLength) {
return NS_OK;
}
// retrieve the laid-out glyph data from the CTRun
UniquePtr<CGGlyph[]> glyphsArray;
UniquePtr<CGPoint[]> positionsArray;
UniquePtr<CFIndex[]> glyphToCharArray;
const CGGlyph* glyphs = nullptr;
const CGPoint* positions = nullptr;
const CFIndex* glyphToChar = nullptr;
// Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
// and so allocating a new array and copying data with CTRunGetGlyphs
// will be extremely rare.
// If this were not the case, we could use an AutoTArray<> to
// try and avoid the heap allocation for small runs.
// It's possible that some future change to CoreText will mean that
// CTRunGetGlyphsPtr fails more often; if this happens, AutoTArray<>
// may become an attractive option.
glyphs = ::CTRunGetGlyphsPtr(aCTRun);
if (!glyphs) {
glyphsArray = MakeUniqueFallible<CGGlyph[]>(numGlyphs);
if (!glyphsArray) {
return NS_ERROR_OUT_OF_MEMORY;
}
::CTRunGetGlyphs(aCTRun, ::CFRangeMake(0, 0), glyphsArray.get());
glyphs = glyphsArray.get();
}
positions = ::CTRunGetPositionsPtr(aCTRun);
if (!positions) {
positionsArray = MakeUniqueFallible<CGPoint[]>(numGlyphs);
if (!positionsArray) {
return NS_ERROR_OUT_OF_MEMORY;
}
::CTRunGetPositions(aCTRun, ::CFRangeMake(0, 0), positionsArray.get());
positions = positionsArray.get();
}
// Remember that the glyphToChar indices relate to the CoreText line,
// not to the beginning of the textRun, the font run,
// or the stringRange of the glyph run
glyphToChar = ::CTRunGetStringIndicesPtr(aCTRun);
if (!glyphToChar) {
glyphToCharArray = MakeUniqueFallible<CFIndex[]>(numGlyphs);
if (!glyphToCharArray) {
return NS_ERROR_OUT_OF_MEMORY;
}
::CTRunGetStringIndices(aCTRun, ::CFRangeMake(0, 0), glyphToCharArray.get());
glyphToChar = glyphToCharArray.get();
}
double runWidth = ::CTRunGetTypographicBounds(aCTRun, ::CFRangeMake(0, 0),
nullptr, nullptr, nullptr);
AutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs() + aOffset;
// CoreText gives us the glyphindex-to-charindex mapping, which relates each glyph
// to a source text character; we also need the charindex-to-glyphindex mapping to
// find the glyph for a given char. Note that some chars may not map to any glyph
// (ligature continuations), and some may map to several glyphs (eg Indic split vowels).
// We set the glyph index to NO_GLYPH for chars that have no associated glyph, and we
// record the last glyph index for cases where the char maps to several glyphs,
// so that our clumping will include all the glyph fragments for the character.
//.........这里部分代码省略.........
示例2: ProcessInput
void TrackUnionStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
{
if (IsFinishedOnGraphThread()) {
return;
}
AutoTArray<bool,8> mappedTracksFinished;
AutoTArray<bool,8> mappedTracksWithMatchingInputTracks;
for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
mappedTracksFinished.AppendElement(true);
mappedTracksWithMatchingInputTracks.AppendElement(false);
}
bool allFinished = !mInputs.IsEmpty();
bool allHaveCurrentData = !mInputs.IsEmpty();
for (uint32_t i = 0; i < mInputs.Length(); ++i) {
MediaStream* stream = mInputs[i]->GetSource();
if (!stream->IsFinishedOnGraphThread()) {
// XXX we really should check whether 'stream' has finished within time aTo,
// not just that it's finishing when all its queued data eventually runs
// out.
allFinished = false;
}
if (!stream->HasCurrentData()) {
allHaveCurrentData = false;
}
bool trackAdded = false;
for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer());
!tracks.IsEnded(); tracks.Next()) {
bool found = false;
for (uint32_t j = 0; j < mTrackMap.Length(); ++j) {
TrackMapEntry* map = &mTrackMap[j];
if (map->mInputPort == mInputs[i] && map->mInputTrackID == tracks->GetID()) {
bool trackFinished;
StreamBuffer::Track* outputTrack = mBuffer.FindTrack(map->mOutputTrackID);
found = true;
if (!outputTrack || outputTrack->IsEnded() ||
!mInputs[i]->PassTrackThrough(tracks->GetID())) {
trackFinished = true;
} else {
CopyTrackData(tracks.get(), j, aFrom, aTo, &trackFinished);
}
mappedTracksFinished[j] = trackFinished;
mappedTracksWithMatchingInputTracks[j] = true;
break;
}
}
if (!found && mInputs[i]->PassTrackThrough(tracks->GetID())) {
bool trackFinished = false;
trackAdded = true;
uint32_t mapIndex = AddTrack(mInputs[i], tracks.get(), aFrom);
CopyTrackData(tracks.get(), mapIndex, aFrom, aTo, &trackFinished);
mappedTracksFinished.AppendElement(trackFinished);
mappedTracksWithMatchingInputTracks.AppendElement(true);
}
}
if (trackAdded) {
for (MediaStreamListener* l : mListeners) {
l->NotifyFinishedTrackCreation(Graph());
}
}
}
for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
if (mappedTracksFinished[i]) {
EndTrack(i);
} else {
allFinished = false;
}
if (!mappedTracksWithMatchingInputTracks[i]) {
mTrackMap.RemoveElementAt(i);
}
}
if (allFinished && mAutofinish && (aFlags & ALLOW_FINISH)) {
// All streams have finished and won't add any more tracks, and
// all our tracks have actually finished and been removed from our map,
// so we're finished now.
FinishOnGraphThread();
} else {
mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking(aTo));
}
if (allHaveCurrentData) {
// We can make progress if we're not blocked
mHasCurrentData = true;
}
}
示例3: range
void
MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
mozilla::gfx::DrawTarget* aRefDrawTarget,
gfxMissingFontRecorder* aMFR)
{
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
nsAutoString convertedString;
AutoTArray<bool,50> charsToMergeArray;
AutoTArray<bool,50> deletedCharsArray;
AutoTArray<RefPtr<nsTransformedCharStyle>,50> styleArray;
AutoTArray<uint8_t,50> canBreakBeforeArray;
bool mergeNeeded = false;
bool singleCharMI =
!!(aTextRun->GetFlags2() & nsTextFrameUtils::Flags::TEXT_IS_SINGLE_CHAR_MI);
uint32_t length = aTextRun->GetLength();
const char16_t* str = aTextRun->mString.BeginReading();
const nsTArray<RefPtr<nsTransformedCharStyle>>& styles = aTextRun->mStyles;
nsFont font;
if (length) {
font = styles[0]->mFont;
if (mSSTYScriptLevel || (mFlags & MATH_FONT_FEATURE_DTLS)) {
bool foundSSTY = false;
bool foundDTLS = false;
// We respect ssty settings explicitly set by the user
for (uint32_t i = 0; i < font.fontFeatureSettings.Length(); i++) {
if (font.fontFeatureSettings[i].mTag == TT_SSTY) {
foundSSTY = true;
} else if (font.fontFeatureSettings[i].mTag == TT_DTLS) {
foundDTLS = true;
}
}
if (mSSTYScriptLevel && !foundSSTY) {
uint8_t sstyLevel = 0;
float scriptScaling = pow(styles[0]->mScriptSizeMultiplier,
mSSTYScriptLevel);
static_assert(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER < 1,
"Shouldn't it make things smaller?");
/*
An SSTY level of 2 is set if the scaling factor is less than or equal
to halfway between that for a scriptlevel of 1 (0.71) and that of a
scriptlevel of 2 (0.71^2), assuming the default script size multiplier.
An SSTY level of 1 is set if the script scaling factor is less than
or equal that for a scriptlevel of 1 assuming the default script size
multiplier.
User specified values of script size multiplier will change the scaling
factor which mSSTYScriptLevel values correspond to.
In the event that the script size multiplier actually makes things
larger, no change is made.
To opt out of this change, add the following to the stylesheet:
"font-feature-settings: 'ssty' 0"
*/
if (scriptScaling <= (NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER +
(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER *
NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER))/2) {
// Currently only the first two ssty settings are used, so two is large
// as we go
sstyLevel = 2;
} else if (scriptScaling <= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER) {
sstyLevel = 1;
}
if (sstyLevel) {
gfxFontFeature settingSSTY;
settingSSTY.mTag = TT_SSTY;
settingSSTY.mValue = sstyLevel;
font.fontFeatureSettings.AppendElement(settingSSTY);
}
}
/*
Apply the dtls font feature setting (dotless).
This gets applied to the base frame and all descendants of the base
frame of certain <mover> and <munderover> frames.
See nsMathMLmunderoverFrame.cpp for a full description.
To opt out of this change, add the following to the stylesheet:
"font-feature-settings: 'dtls' 0"
*/
if ((mFlags & MATH_FONT_FEATURE_DTLS) && !foundDTLS) {
gfxFontFeature settingDTLS;
settingDTLS.mTag = TT_DTLS;
settingDTLS.mValue = 1;
font.fontFeatureSettings.AppendElement(settingDTLS);
}
}
}
uint8_t mathVar = NS_MATHML_MATHVARIANT_NONE;
bool doMathvariantStyling = true;
for (uint32_t i = 0; i < length; ++i) {
int extraChars = 0;
mathVar = styles[i]->mMathVariant;
//.........这里部分代码省略.........
示例4: TRACE_AUDIO_CALLBACK_COMMENT
void TrackUnionStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
uint32_t aFlags) {
TRACE_AUDIO_CALLBACK_COMMENT("TrackUnionStream %p", this);
if (IsFinishedOnGraphThread()) {
return;
}
AutoTArray<bool, 8> mappedTracksFinished;
AutoTArray<bool, 8> mappedTracksWithMatchingInputTracks;
for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
mappedTracksFinished.AppendElement(true);
mappedTracksWithMatchingInputTracks.AppendElement(false);
}
AutoTArray<MediaInputPort*, 32> inputs(mInputs);
inputs.AppendElements(mSuspendedInputs);
bool allFinished = !inputs.IsEmpty();
bool allHaveCurrentData = !inputs.IsEmpty();
for (uint32_t i = 0; i < inputs.Length(); ++i) {
MediaStream* stream = inputs[i]->GetSource();
if (!stream->IsFinishedOnGraphThread()) {
// XXX we really should check whether 'stream' has finished within time
// aTo, not just that it's finishing when all its queued data eventually
// runs out.
allFinished = false;
}
if (!stream->HasCurrentData()) {
allHaveCurrentData = false;
}
for (StreamTracks::TrackIter tracks(stream->GetStreamTracks());
!tracks.IsEnded(); tracks.Next()) {
bool found = false;
for (uint32_t j = 0; j < mTrackMap.Length(); ++j) {
TrackMapEntry* map = &mTrackMap[j];
if (map->mInputPort == inputs[i] &&
map->mInputTrackID == tracks->GetID()) {
bool trackFinished = false;
StreamTracks::Track* outputTrack =
mTracks.FindTrack(map->mOutputTrackID);
found = true;
if (!outputTrack || outputTrack->IsEnded() ||
!inputs[i]->PassTrackThrough(tracks->GetID())) {
trackFinished = true;
} else {
CopyTrackData(tracks.get(), j, aFrom, aTo, &trackFinished);
}
mappedTracksFinished[j] = trackFinished;
mappedTracksWithMatchingInputTracks[j] = true;
break;
}
}
if (!found && inputs[i]->AllowCreationOf(tracks->GetID())) {
bool trackFinished = false;
uint32_t mapIndex = AddTrack(inputs[i], tracks.get(), aFrom);
CopyTrackData(tracks.get(), mapIndex, aFrom, aTo, &trackFinished);
mappedTracksFinished.AppendElement(trackFinished);
mappedTracksWithMatchingInputTracks.AppendElement(true);
}
}
}
for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
if (mappedTracksFinished[i]) {
EndTrack(i);
} else {
allFinished = false;
}
if (!mappedTracksWithMatchingInputTracks[i]) {
for (auto listener : mTrackMap[i].mOwnedDirectListeners) {
// Remove listeners while the entry still exists.
RemoveDirectTrackListenerImpl(listener, mTrackMap[i].mOutputTrackID);
}
mTrackMap.RemoveElementAt(i);
}
}
if (allFinished && mAutofinish && (aFlags & ALLOW_FINISH)) {
// All streams have finished and won't add any more tracks, and
// all our tracks have actually finished and been removed from our map,
// so we're finished now.
FinishOnGraphThread();
}
if (allHaveCurrentData) {
// We can make progress if we're not blocked
mHasCurrentData = true;
}
}
示例5: transferable
//.........这里部分代码省略.........
for (const JS::Value& value : realTransferable) {
if (!value.isObject()) {
continue;
}
MessagePort* port = nullptr;
nsresult rv = UNWRAP_OBJECT(MessagePort, &value.toObject(), port);
if (NS_FAILED(rv)) {
continue;
}
if (port == this) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return;
}
}
// The input sequence only comes from the generated bindings code, which
// ensures it is rooted.
JS::HandleValueArray elements =
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
realTransferable.Elements());
JSObject* array =
JS_NewArrayObject(aCx, elements);
if (!array) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
transferable.setObject(*array);
}
RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();
UniquePtr<AbstractTimelineMarker> start;
UniquePtr<AbstractTimelineMarker> end;
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
bool isTimelineRecording = timelines && !timelines->IsEmpty();
if (isTimelineRecording) {
start = MakeUnique<MessagePortTimelineMarker>(
ProfileTimelineMessagePortOperationType::SerializeData,
MarkerTracingType::START);
}
data->Write(aCx, aMessage, transferable, aRv);
if (isTimelineRecording) {
end = MakeUnique<MessagePortTimelineMarker>(
ProfileTimelineMessagePortOperationType::SerializeData,
MarkerTracingType::END);
timelines->AddMarkerForAllObservedDocShells(start);
timelines->AddMarkerForAllObservedDocShells(end);
}
if (NS_WARN_IF(aRv.Failed())) {
return;
}
// This message has to be ignored.
if (mState > eStateEntangled) {
return;
}
// If we are unshipped we are connected to the other port on the same thread.
if (mState == eStateUnshippedEntangled) {
MOZ_ASSERT(mUnshippedEntangledPort);
mUnshippedEntangledPort->mMessages.AppendElement(data);
mUnshippedEntangledPort->Dispatch();
return;
}
// Not entangled yet, but already closed/disentangled.
if (mState == eStateEntanglingForDisentangle ||
mState == eStateEntanglingForClose) {
return;
}
RemoveDocFromBFCache();
// Not entangled yet.
if (mState == eStateEntangling) {
mMessagesForTheOtherPort.AppendElement(data);
return;
}
MOZ_ASSERT(mActor);
MOZ_ASSERT(mMessagesForTheOtherPort.IsEmpty());
AutoTArray<RefPtr<SharedMessagePortMessage>, 1> array;
array.AppendElement(data);
AutoTArray<ClonedMessageData, 1> messages;
// note: `messages` will borrow the underlying buffer, but this is okay
// because reverse destruction order means `messages` will be destroyed prior
// to `array`/`data`.
SharedMessagePortMessage::FromSharedToMessagesChild(mActor, array, messages);
mActor->SendPostMessages(messages);
}
示例6: lock
void VideoFrameContainer::SetCurrentFrames(const VideoSegment& aSegment)
{
if (aSegment.IsEmpty()) {
return;
}
MutexAutoLock lock(mMutex);
AutoTimer<Telemetry::VFC_SETVIDEOSEGMENT_LOCK_HOLD_MS> lockHold;
// Collect any new frames produced in this iteration.
AutoTArray<ImageContainer::NonOwningImage,4> newImages;
PrincipalHandle lastPrincipalHandle = PRINCIPAL_HANDLE_NONE;
VideoSegment::ConstChunkIterator iter(aSegment);
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
const VideoFrame* frame = &chunk.mFrame;
if (*frame == mLastPlayedVideoFrame) {
iter.Next();
continue;
}
Image* image = frame->GetImage();
CONTAINER_LOG(LogLevel::Verbose,
("VideoFrameContainer %p writing video frame %p (%d x %d)",
this, image, frame->GetIntrinsicSize().width,
frame->GetIntrinsicSize().height));
if (frame->GetForceBlack()) {
if (!mBlackImage) {
mBlackImage = GetImageContainer()->CreatePlanarYCbCrImage();
if (mBlackImage) {
// Sets the image to a single black pixel, which will be scaled to
// fill the rendered size.
SetImageToBlackPixel(mBlackImage->AsPlanarYCbCrImage());
}
}
if (mBlackImage) {
image = mBlackImage;
}
}
// Don't append null image to the newImages.
if (!image) {
iter.Next();
continue;
}
newImages.AppendElement(ImageContainer::NonOwningImage(image, chunk.mTimeStamp));
lastPrincipalHandle = chunk.GetPrincipalHandle();
mLastPlayedVideoFrame = *frame;
iter.Next();
}
// Don't update if there are no changes.
if (newImages.IsEmpty()) {
return;
}
AutoTArray<ImageContainer::NonOwningImage,4> images;
bool principalHandleChanged =
lastPrincipalHandle != PRINCIPAL_HANDLE_NONE &&
lastPrincipalHandle != GetLastPrincipalHandleLocked();
// Add the frames from this iteration.
for (auto& image : newImages) {
image.mFrameID = NewFrameID();
images.AppendElement(image);
}
if (principalHandleChanged) {
UpdatePrincipalHandleForFrameIDLocked(lastPrincipalHandle,
newImages.LastElement().mFrameID);
}
SetCurrentFramesLocked(mLastPlayedVideoFrame.GetIntrinsicSize(), images);
nsCOMPtr<nsIRunnable> event =
new VideoFrameContainerInvalidateRunnable(this);
mMainThread->Dispatch(event.forget());
images.ClearAndRetainStorage();
}
示例7: gr_seg_n_slots
nsresult
gfxGraphiteShaper::SetGlyphsFromSegment(gfxShapedText *aShapedText,
uint32_t aOffset,
uint32_t aLength,
const char16_t *aText,
gr_segment *aSegment,
RoundingFlags aRounding)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
int32_t dev2appUnits = aShapedText->GetAppUnitsPerDevUnit();
bool rtl = aShapedText->IsRightToLeft();
uint32_t glyphCount = gr_seg_n_slots(aSegment);
// identify clusters; graphite may have reordered/expanded/ligated glyphs.
AutoTArray<Cluster,SMALL_GLYPH_RUN> clusters;
AutoTArray<uint16_t,SMALL_GLYPH_RUN> gids;
AutoTArray<float,SMALL_GLYPH_RUN> xLocs;
AutoTArray<float,SMALL_GLYPH_RUN> yLocs;
if (!clusters.SetLength(aLength, fallible) ||
!gids.SetLength(glyphCount, fallible) ||
!xLocs.SetLength(glyphCount, fallible) ||
!yLocs.SetLength(glyphCount, fallible))
{
return NS_ERROR_OUT_OF_MEMORY;
}
// walk through the glyph slots and check which original character
// each is associated with
uint32_t gIndex = 0; // glyph slot index
uint32_t cIndex = 0; // current cluster index
for (const gr_slot *slot = gr_seg_first_slot(aSegment);
slot != nullptr;
slot = gr_slot_next_in_segment(slot), gIndex++)
{
uint32_t before =
gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_before(slot)));
uint32_t after =
gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_after(slot)));
gids[gIndex] = gr_slot_gid(slot);
xLocs[gIndex] = gr_slot_origin_X(slot);
yLocs[gIndex] = gr_slot_origin_Y(slot);
// if this glyph has a "before" character index that precedes the
// current cluster's char index, we need to merge preceding
// clusters until it gets included
while (before < clusters[cIndex].baseChar && cIndex > 0) {
clusters[cIndex-1].nChars += clusters[cIndex].nChars;
clusters[cIndex-1].nGlyphs += clusters[cIndex].nGlyphs;
--cIndex;
}
// if there's a gap between the current cluster's base character and
// this glyph's, extend the cluster to include the intervening chars
if (gr_slot_can_insert_before(slot) && clusters[cIndex].nChars &&
before >= clusters[cIndex].baseChar + clusters[cIndex].nChars)
{
NS_ASSERTION(cIndex < aLength - 1, "cIndex at end of word");
Cluster& c = clusters[cIndex + 1];
c.baseChar = clusters[cIndex].baseChar + clusters[cIndex].nChars;
c.nChars = before - c.baseChar;
c.baseGlyph = gIndex;
c.nGlyphs = 0;
++cIndex;
}
// increment cluster's glyph count to include current slot
NS_ASSERTION(cIndex < aLength, "cIndex beyond word length");
++clusters[cIndex].nGlyphs;
// bump |after| index if it falls in the middle of a surrogate pair
if (NS_IS_HIGH_SURROGATE(aText[after]) && after < aLength - 1 &&
NS_IS_LOW_SURROGATE(aText[after + 1])) {
after++;
}
// extend cluster if necessary to reach the glyph's "after" index
if (clusters[cIndex].baseChar + clusters[cIndex].nChars < after + 1) {
clusters[cIndex].nChars = after + 1 - clusters[cIndex].baseChar;
}
}
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
bool roundX = bool(aRounding & RoundingFlags::kRoundX);
bool roundY = bool(aRounding & RoundingFlags::kRoundY);
// now put glyphs into the textrun, one cluster at a time
for (uint32_t i = 0; i <= cIndex; ++i) {
const Cluster& c = clusters[i];
float adv; // total advance of the cluster
if (rtl) {
if (i == 0) {
adv = gr_seg_advance_X(aSegment) - xLocs[c.baseGlyph];
} else {
adv = xLocs[clusters[i-1].baseGlyph] - xLocs[c.baseGlyph];
}
} else {
//.........这里部分代码省略.........
示例8: AssertOwnerThread
void
DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle)
{
AssertOwnerThread();
if (!mInfo.HasVideo()) {
return;
}
VideoSegment output;
TrackID videoTrackId = mInfo.mVideo.mTrackId;
AutoTArray<RefPtr<VideoData>, 10> video;
SourceMediaStream* sourceStream = mData->mStream;
// It's OK to hold references to the VideoData because VideoData
// is ref-counted.
mVideoQueue.GetElementsAfter(mData->mNextVideoTime, &video);
// tracksStartTimeStamp might be null when the SourceMediaStream not yet
// be added to MediaStreamGraph.
TimeStamp tracksStartTimeStamp = sourceStream->GetStreamTracksStrartTimeStamp();
if (tracksStartTimeStamp.IsNull()) {
tracksStartTimeStamp = TimeStamp::Now();
}
for (uint32_t i = 0; i < video.Length(); ++i) {
VideoData* v = video[i];
if (mData->mNextVideoTime < v->mTime) {
// Write last video frame to catch up. mLastVideoImage can be null here
// which is fine, it just means there's no video.
// TODO: |mLastVideoImage| should come from the last image rendered
// by the state machine. This will avoid the black frame when capture
// happens in the middle of playback (especially in th middle of a
// video frame). E.g. if we have a video frame that is 30 sec long
// and capture happens at 15 sec, we'll have to append a black frame
// that is 15 sec long.
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage, v->mTime,
mData->mNextVideoTime, mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + v->mTime.ToTimeDuration(),
&output, aPrincipalHandle);
mData->mNextVideoTime = v->mTime;
}
if (mData->mNextVideoTime < v->GetEndTime()) {
WriteVideoToMediaStream(sourceStream, v->mImage, v->GetEndTime(),
mData->mNextVideoTime, v->mDisplay,
tracksStartTimeStamp + v->GetEndTime().ToTimeDuration(),
&output, aPrincipalHandle);
mData->mNextVideoTime = v->GetEndTime();
mData->mLastVideoImage = v->mImage;
mData->mLastVideoImageDisplaySize = v->mDisplay;
}
}
// Check the output is not empty.
if (output.GetLastFrame()) {
mData->mEOSVideoCompensation = ZeroDurationAtLastChunk(output);
}
if (!aIsSameOrigin) {
output.ReplaceWithDisabled();
}
if (output.GetDuration() > 0) {
sourceStream->AppendToTrack(videoTrackId, &output);
}
if (mVideoQueue.IsFinished() && !mData->mHaveSentFinishVideo) {
if (mData->mEOSVideoCompensation) {
VideoSegment endSegment;
// Calculate the deviation clock time from DecodedStream.
auto deviation = FromMicroseconds(sourceStream->StreamTimeToMicroseconds(1));
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage,
mData->mNextVideoTime + deviation, mData->mNextVideoTime,
mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + (mData->mNextVideoTime + deviation).ToTimeDuration(),
&endSegment, aPrincipalHandle);
mData->mNextVideoTime += deviation;
MOZ_ASSERT(endSegment.GetDuration() > 0);
if (!aIsSameOrigin) {
endSegment.ReplaceWithDisabled();
}
sourceStream->AppendToTrack(videoTrackId, &endSegment);
}
sourceStream->EndTrack(videoTrackId);
mData->mHaveSentFinishVideo = true;
}
}
示例9: MarkInReflow
/* virtual */ void
nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsRubyBaseContainerFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
aStatus = NS_FRAME_COMPLETE;
if (!aReflowState.mLineLayout) {
NS_ASSERTION(
aReflowState.mLineLayout,
"No line layout provided to RubyBaseContainerFrame reflow method.");
return;
}
MoveOverflowToChildList();
// Ask text containers to drain overflows
AutoRubyTextContainerArray textContainers(this);
const uint32_t rtcCount = textContainers.Length();
for (uint32_t i = 0; i < rtcCount; i++) {
textContainers[i]->MoveOverflowToChildList();
}
WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode();
LogicalSize availSize(lineWM, aReflowState.AvailableISize(),
aReflowState.AvailableBSize());
// We have a reflow state and a line layout for each RTC.
// They are conceptually the state of the RTCs, but we don't actually
// reflow those RTCs in this code. These two arrays are holders of
// the reflow states and line layouts.
// Since there are pointers refer to reflow states and line layouts,
// it is necessary to guarantee that they won't be moved. For this
// reason, they are wrapped in UniquePtr here.
AutoTArray<UniquePtr<nsHTMLReflowState>, RTC_ARRAY_SIZE> reflowStates;
AutoTArray<UniquePtr<nsLineLayout>, RTC_ARRAY_SIZE> lineLayouts;
reflowStates.SetCapacity(rtcCount);
lineLayouts.SetCapacity(rtcCount);
// Begin the line layout for each ruby text container in advance.
bool hasSpan = false;
for (uint32_t i = 0; i < rtcCount; i++) {
nsRubyTextContainerFrame* textContainer = textContainers[i];
if (textContainer->IsSpanContainer()) {
hasSpan = true;
}
nsHTMLReflowState* reflowState = new nsHTMLReflowState(
aPresContext, *aReflowState.mParentReflowState, textContainer,
availSize.ConvertTo(textContainer->GetWritingMode(), lineWM));
reflowStates.AppendElement(reflowState);
nsLineLayout* lineLayout = new nsLineLayout(aPresContext,
reflowState->mFloatManager,
reflowState, nullptr,
aReflowState.mLineLayout);
lineLayout->SetSuppressLineWrap(true);
lineLayouts.AppendElement(lineLayout);
// Line number is useless for ruby text
// XXX nullptr here may cause problem, see comments for
// nsLineLayout::mBlockRS and nsLineLayout::AddFloat
lineLayout->Init(nullptr, reflowState->CalcLineHeight(), -1);
reflowState->mLineLayout = lineLayout;
// Border and padding are suppressed on ruby text containers.
// If the writing mode is vertical-rl, the horizontal position of
// rt frames will be updated when reflowing this text container,
// hence leave container size 0 here for now.
lineLayout->BeginLineReflow(0, 0, reflowState->ComputedISize(),
NS_UNCONSTRAINEDSIZE,
false, false, lineWM, nsSize(0, 0));
lineLayout->AttachRootFrameToBaseLineLayout();
}
aReflowState.mLineLayout->BeginSpan(this, &aReflowState,
0, aReflowState.AvailableISize(),
&mBaseline);
bool allowInitialLineBreak, allowLineBreak;
GetIsLineBreakAllowed(this, aReflowState.mLineLayout->LineIsBreakable(),
&allowInitialLineBreak, &allowLineBreak);
nscoord isize = 0;
// Reflow columns excluding any span
ReflowState reflowState = {
allowInitialLineBreak, allowLineBreak && !hasSpan,
textContainers, aReflowState, reflowStates
};
isize = ReflowColumns(reflowState, aStatus);
DebugOnly<nscoord> lineSpanSize = aReflowState.mLineLayout->EndSpan(this);
aDesiredSize.ISize(lineWM) = isize;
// When there are no frames inside the ruby base container, EndSpan
// will return 0. However, in this case, the actual width of the
// container could be non-zero because of non-empty ruby annotations.
// XXX When bug 765861 gets fixed, this warning should be upgraded.
NS_WARN_IF_FALSE(NS_INLINE_IS_BREAK(aStatus) ||
isize == lineSpanSize || mFrames.IsEmpty(), "bad isize");
//.........这里部分代码省略.........
示例10: font
int CALLBACK GDIFontInfo::EnumerateFontsForFamily(
const ENUMLOGFONTEXW *lpelfe,
const NEWTEXTMETRICEXW *nmetrics,
DWORD fontType, LPARAM data)
{
EnumerateFontsForFamilyData *famData =
reinterpret_cast<EnumerateFontsForFamilyData*>(data);
HDC hdc = famData->mFontInfo.mHdc;
LOGFONTW logFont = lpelfe->elfLogFont;
const NEWTEXTMETRICW& metrics = nmetrics->ntmTm;
AutoSelectFont font(hdc, &logFont);
if (!font.IsValid()) {
return 1;
}
FontFaceData fontData;
nsDependentString fontName(lpelfe->elfFullName);
// callback called for each style-charset so return if style already seen
if (fontName.Equals(famData->mPreviousFontName)) {
return 1;
}
famData->mPreviousFontName = fontName;
famData->mFontInfo.mLoadStats.fonts++;
// read name table info
bool nameDataLoaded = false;
if (famData->mFontInfo.mLoadFaceNames || famData->mFontInfo.mLoadOtherNames) {
uint32_t kNAME =
NativeEndian::swapToBigEndian(TRUETYPE_TAG('n','a','m','e'));
uint32_t nameSize;
AutoTArray<uint8_t, 1024> nameData;
nameSize = ::GetFontData(hdc, kNAME, 0, nullptr, 0);
if (nameSize != GDI_ERROR &&
nameSize > 0 &&
nameData.SetLength(nameSize, fallible)) {
::GetFontData(hdc, kNAME, 0, nameData.Elements(), nameSize);
// face names
if (famData->mFontInfo.mLoadFaceNames) {
gfxFontUtils::ReadCanonicalName((const char*)(nameData.Elements()), nameSize,
gfxFontUtils::NAME_ID_FULL,
fontData.mFullName);
gfxFontUtils::ReadCanonicalName((const char*)(nameData.Elements()), nameSize,
gfxFontUtils::NAME_ID_POSTSCRIPT,
fontData.mPostscriptName);
nameDataLoaded = true;
famData->mFontInfo.mLoadStats.facenames++;
}
// other family names
if (famData->mFontInfo.mLoadOtherNames) {
gfxFontFamily::ReadOtherFamilyNamesForFace(famData->mFamilyName,
(const char*)(nameData.Elements()),
nameSize,
famData->mOtherFamilyNames,
false);
}
}
}
// read cmap
bool cmapLoaded = false;
gfxWindowsFontType feType =
GDIFontEntry::DetermineFontType(metrics, fontType);
if (famData->mFontInfo.mLoadCmaps &&
(feType == GFX_FONT_TYPE_PS_OPENTYPE ||
feType == GFX_FONT_TYPE_TT_OPENTYPE ||
feType == GFX_FONT_TYPE_TRUETYPE))
{
uint32_t kCMAP =
NativeEndian::swapToBigEndian(TRUETYPE_TAG('c','m','a','p'));
uint32_t cmapSize;
AutoTArray<uint8_t, 1024> cmapData;
cmapSize = ::GetFontData(hdc, kCMAP, 0, nullptr, 0);
if (cmapSize != GDI_ERROR &&
cmapSize > 0 &&
cmapData.SetLength(cmapSize, fallible)) {
::GetFontData(hdc, kCMAP, 0, cmapData.Elements(), cmapSize);
bool cmapLoaded = false;
bool unicodeFont = false, symbolFont = false;
RefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
uint32_t offset;
if (NS_SUCCEEDED(gfxFontUtils::ReadCMAP(cmapData.Elements(),
cmapSize, *charmap,
offset, unicodeFont,
symbolFont))) {
fontData.mCharacterMap = charmap;
fontData.mUVSOffset = offset;
fontData.mSymbolFont = symbolFont;
cmapLoaded = true;
famData->mFontInfo.mLoadStats.cmaps++;
}
}
}
//.........这里部分代码省略.........
示例11: PROFILER_LABEL_FUNC
nsresult
GDIFontEntry::ReadCMAP(FontInfoData *aFontInfoData)
{
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
// attempt this once, if errors occur leave a blank cmap
if (mCharacterMap) {
return NS_OK;
}
// skip non-SFNT fonts completely
if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TT_OPENTYPE &&
mFontType != GFX_FONT_TYPE_TRUETYPE)
{
mCharacterMap = new gfxCharacterMap();
mCharacterMap->mBuildOnTheFly = true;
return NS_ERROR_FAILURE;
}
RefPtr<gfxCharacterMap> charmap;
nsresult rv;
bool unicodeFont = false, symbolFont = false;
if (aFontInfoData && (charmap = GetCMAPFromFontInfo(aFontInfoData,
mUVSOffset,
symbolFont))) {
mSymbolFont = symbolFont;
rv = NS_OK;
} else {
uint32_t kCMAP = TRUETYPE_TAG('c','m','a','p');
charmap = new gfxCharacterMap();
AutoTArray<uint8_t, 16384> cmap;
rv = CopyFontTable(kCMAP, cmap);
if (NS_SUCCEEDED(rv)) {
rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
*charmap, mUVSOffset,
unicodeFont, symbolFont);
}
mSymbolFont = symbolFont;
}
mHasCmapTable = NS_SUCCEEDED(rv);
if (mHasCmapTable) {
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
mCharacterMap = pfl->FindCharMap(charmap);
} else {
// if error occurred, initialize to null cmap
mCharacterMap = new gfxCharacterMap();
// For fonts where we failed to read the character map,
// we can take a slow path to look up glyphs character by character
mCharacterMap->mBuildOnTheFly = true;
}
LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
NS_ConvertUTF16toUTF8(mName).get(),
charmap->SizeOfIncludingThis(moz_malloc_size_of),
charmap->mHash, mCharacterMap == charmap ? " new" : ""));
if (LOG_CMAPDATA_ENABLED()) {
char prefix[256];
sprintf(prefix, "(cmapdata) name: %.220s",
NS_ConvertUTF16toUTF8(mName).get());
charmap->Dump(prefix, eGfxLog_cmapdata);
}
return rv;
}
示例12: IsInterfaceEqualToOrInheritedFrom
bool
IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
unsigned long aVtableIndexHint)
{
if (aInterface == aFrom) {
return true;
}
// We expect this array to be length 1 but that is not guaranteed by the API.
AutoTArray<RefPtr<ITypeInfo>, 1> typeInfos;
// Grab aInterface's ITypeInfo so that we may obtain information about its
// inheritance hierarchy.
RefPtr<ITypeInfo> typeInfo;
if (RegisteredProxy::Find(aInterface, getter_AddRefs(typeInfo))) {
typeInfos.AppendElement(Move(typeInfo));
}
/**
* The main loop of this function searches the hierarchy of aInterface's
* parent interfaces, searching for aFrom.
*/
while (!typeInfos.IsEmpty()) {
RefPtr<ITypeInfo> curTypeInfo(Move(typeInfos.LastElement()));
typeInfos.RemoveElementAt(typeInfos.Length() - 1);
TYPEATTR* typeAttr = nullptr;
HRESULT hr = curTypeInfo->GetTypeAttr(&typeAttr);
if (FAILED(hr)) {
break;
}
bool isFromParentVtable = IsVtableIndexFromParentInterface(typeAttr,
aVtableIndexHint);
WORD numParentInterfaces = typeAttr->cImplTypes;
curTypeInfo->ReleaseTypeAttr(typeAttr);
typeAttr = nullptr;
if (!isFromParentVtable) {
// The vtable index cannot belong to this interface (otherwise the IIDs
// would already have matched and we would have returned true). Since we
// now also know that the vtable index cannot possibly be contained inside
// curTypeInfo's parent interface, there is no point searching any further
// up the hierarchy from here. OTOH we still should check any remaining
// entries that are still in the typeInfos array, so we continue.
continue;
}
for (WORD i = 0; i < numParentInterfaces; ++i) {
HREFTYPE refCookie;
hr = curTypeInfo->GetRefTypeOfImplType(i, &refCookie);
if (FAILED(hr)) {
continue;
}
RefPtr<ITypeInfo> nextTypeInfo;
hr = curTypeInfo->GetRefTypeInfo(refCookie,
getter_AddRefs(nextTypeInfo));
if (FAILED(hr)) {
continue;
}
hr = nextTypeInfo->GetTypeAttr(&typeAttr);
if (FAILED(hr)) {
continue;
}
IID nextIid = typeAttr->guid;
nextTypeInfo->ReleaseTypeAttr(typeAttr);
typeAttr = nullptr;
if (nextIid == aFrom) {
return true;
}
typeInfos.AppendElement(Move(nextTypeInfo));
}
}
return false;
}