static double neighbourStackCorrection(ParticleType b1, ParticleType b2, int monomerDistance) { assert(isBase(b1) && isBase(b2)); assert(0 <= monomerDistance && monomerDistance <= 1); return neighbourStackCorrectionLUT[b1][b2][monomerDistance]; }
static void initSugarBaseBondDistanceLUT(void) { for (int b = 0; b < NUM_BASE_TYPES; b++) { assert(isBase(b)); switch (b) { case BASE_A: sugarBaseBondDistanceLUT[b] = BOND_S_A; break; case BASE_T: sugarBaseBondDistanceLUT[b] = BOND_S_T; break; case BASE_C: sugarBaseBondDistanceLUT[b] = BOND_S_C; break; case BASE_G: sugarBaseBondDistanceLUT[b] = BOND_S_G; break; case BASE_X: sugarBaseBondDistanceLUT[b] = BOND_S_X; break; case BASE_Y: sugarBaseBondDistanceLUT[b] = BOND_S_Y; break; default: die("Unknown base type %d in " "initSugarBaseBondDistanceLUT!\n", b); } } }
static void initAngleBaseInfoLUT(void) { for (int b = 0; b < NUM_BASE_TYPES; b++) { assert(isBase(b)); switch (b) { case BASE_A: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_A; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_A; break; case BASE_T: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_T; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_T; break; case BASE_C: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_C; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_C; break; case BASE_G: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_G; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_G; break; case BASE_X: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_X; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_X; break; case BASE_Y: angleBaseInfoLUT[b].P5SB = ANGLE_P_5S_Y; angleBaseInfoLUT[b].P3SB = ANGLE_P_3S_Y; break; default: die("Unknown base type %d in initAngleBaseInfoLUT!\n", b); } } }
void Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transform) { m_layers.append(layer); SkSafeRef(layer); m_needsTexture |= layer->needsTexture(); m_hasText |= layer->hasText(); // add this layer's size to the surface's area // TODO: handle scale/3d transform mapping IntRect rect = enclosingIntRect(layer->fullContentAreaMapped()); if (layer->needsTexture()) { if (m_fullContentArea.isEmpty()) { m_drawTransform = transform; m_drawTransform.translate3d(-rect.x(), -rect.y(), 0); m_fullContentArea = rect; } else m_fullContentArea.unite(rect); ALOGV("Surf %p adding LA %p, size " INT_RECT_FORMAT " now fullContentArea " INT_RECT_FORMAT, this, layer, INT_RECT_ARGS(rect), INT_RECT_ARGS(m_fullContentArea)); } if (isBase()) m_background = static_cast<BaseLayerAndroid*>(layer)->getBackgroundColor(); }
IntRect Surface::computePrepareArea() { IntRect area; if (!getFirstLayer()->contentIsScrollable() && !isBase() && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { area = fullContentArea(); double total = ((double) area.width()) * ((double) area.height()); if (total > MAX_FULL_CONTENT_AREA) area = visibleContentArea(); /// M: Willy, limit the max number of tile is 64. @{ else { float scale = getFirstLayer()->state()->scale(); int x = ((double)area.width() * scale) / TilesManager::tileWidth(); int y = ((double)area.height() * scale) / TilesManager::tileHeight(); if ((x * y) > 64) { IntRect a = visibleContentArea(); IntRect tmpArea = a; tmpArea.inflateX(TilesManager::tileWidth() << 1); tmpArea.inflateY(TilesManager::tileHeight() << 1); tmpArea.intersect(area); area = tmpArea; } } /// @} } else area = visibleContentArea(); return area; }
void RNAProfileAlignment::getStructAli(string &s,Uint row) const { s=""; map<Uint,Uint> pairs; makePairTable(pairs, row); // iterate through leaves nodes and use information of pairs for(Uint i=0;i<m_size;i++) { RNA_Alphabet c; c=m_lb[i].columnStr[row]; if(isBase(i)) { if(c != '-') { if(pairs.find(i) != pairs.end()) // is base paired ? { Uint j=pairs[i]; if(i<j) s+='('; else s+=')'; } else s+='.'; } else s+='-'; } } }
bool Surface::paint(SkCanvas* canvas) { if (singleLayer()) { getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); // TODO: double buffer by disabling SurfaceCollection swaps and position // updates until painting complete // In single surface mode, draw layer content onto the base layer if (isBase() && getFirstLayer()->countChildren() && getFirstLayer()->state()->isSingleSurfaceRenderingMode()) { for (int i = 0; i < getFirstLayer()->countChildren(); i++) getFirstLayer()->getChild(i)->drawCanvas(canvas, true, Layer::FlattenedLayers); } } else { SkAutoCanvasRestore acr(canvas, true); SkMatrix matrix; GLUtils::toSkMatrix(matrix, m_drawTransform); SkMatrix inverse; inverse.reset(); matrix.invert(&inverse); SkMatrix canvasMatrix = canvas->getTotalMatrix(); inverse.postConcat(canvasMatrix); canvas->setMatrix(inverse); for (unsigned int i=0; i<m_layers.size(); i++) m_layers[i]->drawCanvas(canvas, false, Layer::MergedLayers); } return true; }
int choosePinIdx(int note, int channel) { int instr = playChannels[channel]; if( isPercussion(instr) && PERCUSSION_PIN_IDX != -1 ) { //printf("Playing percussion channel\n"); return PERCUSSION_PIN_IDX; } else if( isBase(instr) && BASE_PIN_IDX != -1) { //printf("Playing base channel\n"); return BASE_PIN_IDX; } else if( isSynth(instr) && SYNTH_PIN_IDX != -1) { //printf("Playing synth channel\n"); return SYNTH_PIN_IDX; } else { //Is a melody type instrument //There are 12 different kinds of notes. int noteMod = note % 12; //Cast to double double noteModDouble = noteMod; //The pin to use is determined by: // ( pitch / ( Total number of notes / Total Number of Pins) ) double noteBin = noteModDouble / (12.0 / NUM_MELODY_PINS); //Cast back to int int pinIdx = (int)noteBin; return pinIdx; } }
static BasePairInfo getBasePairInfo(Particle *p1, Particle *p2) { ParticleType t1 = p1->type; ParticleType t2 = p2->type; BasePairInfo bpiNULL; bpiNULL.coupling = -1; bpiNULL.distance2 = -1; if (!isBase(t1) || !isBase(t2)) return bpiNULL; switch (interactions.basePairInteraction) { case BASE_PAIR_ALL: break; case BASE_PAIR_XY_HAIRPIN_REST_ALL: /* If we don't have an XY pair... */ if ( !( (t1 == BASE_X && t2 == BASE_Y) || (t1 == BASE_Y && t2 == BASE_X))) break; /* ...then behave like BASE_PAIR_ALL */ /* We have an XY pair -> behave like BASE_PAIR_HAIRPIN */ /* <Intentional case fall through!> */ case BASE_PAIR_HAIRPIN: if (p1->strand != p2->strand) return bpiNULL; int n = p1->strand->numMonomers; int i1 = p1->strandIndex; int i2 = p2->strandIndex; if (i1 != n - 1 - i2) return bpiNULL; break; case BASE_PAIR_DOUBLE_STRAND: if (p1->strand == p2->strand) return bpiNULL; if (p1->strandIndex != p2->strandIndex) return bpiNULL; break; default: die("getBasePairInfo: Unknown basePairInteraction!\n"); } assert(isBase(t1) && isBase(t2)); return basePairInfoLUT[t1][t2]; }
bool Surface::useAggressiveRendering() { // When the background is semi-opaque, 0 < alpha < 255, we had to turn off // low res to avoid artifacts from double drawing. // TODO: avoid double drawing for low res tiles. return isBase() && (!m_background.alpha() || !m_background.hasAlpha()); }
/* monomerDistance: * 0 for immediate neighbours (i and i+1) * 1 for next neighbours (i and i+2) */ static double Vstack(Particle *p1, Particle *p2, int monomerDistance) { assert(isBase(p1->type) && isBase(p2->type)); if (!interactions.enableStack) return 0; double rSq = nearestImageDistance2(p1->pos, p2->pos); if (rSq > truncationLenSq) return 0; double rEqSq = neighbourStackDistance2(p1->type, p2->type, monomerDistance); double Vcorr = neighbourStackCorrection(p1->type, p2->type, monomerDistance); double V = calcVLJ(STACK_COUPLING, rEqSq, rSq) - Vcorr; return V; }
static void Fstack(Particle *p1, Particle *p2, int monomerDistance) { assert(isBase(p1->type) && isBase(p2->type)); if (!interactions.enableStack) return; Vec3 r = nearestImageVector(p1->pos, p2->pos); double rSq = length2(r); if (rSq > truncationLenSq) return; double rEqSq = neighbourStackDistance2(p1->type, p2->type, monomerDistance); double FperDist = calcFLJperDistance(STACK_COUPLING, rEqSq, rSq); Vec3 F = scale(r, FperDist); debugVectorSanity(F, "Fstack"); p1->F = add(p1->F, F); p2->F = sub(p2->F, F); }
bool Surface::drawGL(bool layerTilesDisabled) { bool tilesDisabled = layerTilesDisabled && !isBase(); // SAMSUNG CHANGE ++ : google handwriting 'g' icon display issue, Youtube.com 356x2 height line display issue // This patch should be applied with DEV CL 56175 // WAS:if (singleLayer() && !getFirstLayer()->visible()) if (singleLayer() && (!getFirstLayer()->visible() || getFirstLayer()->drawOpacity() <= 0.0f)) return false; //SAMSUNG CHANGE -- if (!isBase()) { FloatRect drawClip = getFirstLayer()->drawClip(); if (!singleLayer()) { for (unsigned int i = 1; i < m_layers.size(); i++) drawClip.unite(m_layers[i]->drawClip()); } FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip); TilesManager::instance()->shader()->clip(clippingRect); } bool askRedraw = false; if (m_surfaceBacking && !tilesDisabled) { ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking, getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId()); bool force3dContentVisible = true; IntRect drawArea = visibleContentArea(force3dContentVisible); m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), useAggressiveRendering(), background()); } // draw member layers (draws image textures, glextras) for (unsigned int i = 0; i < m_layers.size(); i++) { if (m_layers[i]->drawGL(tilesDisabled)) { m_layers[i]->addDirtyArea(); askRedraw = true; } } return askRedraw; }
// =================================================== // Private Methods // =================================================== void BCInterfaceData::readBase( const GetPot& dataFile, const std::string& path, std::pair< std::string, baseList_Type >& base, std::string& baseString ) { for ( std::map< std::string, baseList_Type >::iterator j = M_mapBase.begin(); j != M_mapBase.end(); ++j ) if ( isBase( dataFile, ( path + j->first ).c_str(), baseString ) ) { base.first = j->first; base.second = M_mapBase[j->first]; break; } }
void Surface::computeTexturesAmount(TexturesResult* result) { if (!m_surfaceBacking || isBase()) return; LayerAndroid* layer = 0; if (singleLayer()) layer = getFirstLayer(); m_surfaceBacking->computeTexturesAmount(result, visibleContentArea(), fullContentArea(), layer); }
void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit) { bool tilesDisabled = layerTilesDisabled && !isBase(); if (!m_surfaceBacking) { ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d", this, m_surfaceBacking, needsTexture()); if (needsTexture() || (isBase() && layerTilesDisabled)) m_surfaceBacking = new SurfaceBacking(isBase()); else return; } if (tilesDisabled) { m_surfaceBacking->discardTextures(); } else { bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors IntRect prepareArea = computePrepareArea(); IntRect fullArea = fullContentArea(); ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers, first layer %s (%d) " "prepareArea(%d, %d - %d x %d) fullArea(%d, %d - %d x %d)", this, m_surfaceBacking, m_layers.size(), getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId(), prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(), fullArea.x(), fullArea.y(), fullArea.width(), fullArea.height()); m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom, prepareArea, fullArea, this, useAggressiveRendering(), updateWithBlit); } for (size_t i = 0; i < m_layers.size(); i++) { LayerContent* content = m_layers[i]->content(); if (content) content->clearPrerenders(); } }
bool Surface::drawGL(bool layerTilesDisabled) { bool tilesDisabled = layerTilesDisabled && !isBase(); if (singleLayer() && !getFirstLayer()->visible()) return false; if (!isBase()) { FloatRect drawClip = getFirstLayer()->drawClip(); if (!singleLayer()) { for (unsigned int i = 1; i < m_layers.size(); i++) drawClip.unite(m_layers[i]->drawClip()); } FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip); TilesManager::instance()->shader()->clip(clippingRect); } bool askRedraw = false; if (m_surfaceBacking && !tilesDisabled) { ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking, getFirstLayer()->subclassName(), getFirstLayer()->uniqueId()); bool force3dContentVisible = true; IntRect drawArea = visibleContentArea(force3dContentVisible); m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), useAggressiveRendering(), background()); } // draw member layers (draws image textures, glextras) for (unsigned int i = 0; i < m_layers.size(); i++) { if (m_layers[i]->drawGL(tilesDisabled)) { m_layers[i]->addDirtyArea(); askRedraw = true; } } return askRedraw; }
IntRect Surface::computePrepareArea() { IntRect area; if (!getFirstLayer()->contentIsScrollable() && !isBase() && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { area = fullContentArea(); double total = ((double) area.width()) * ((double) area.height()); if (total > MAX_FULL_CONTENT_AREA) area = visibleContentArea(); } else area = visibleContentArea(); return area; }
IntRect Surface::computePrepareArea() { IntRect area; if (!getFirstLayer()->contentIsScrollable() && !isBase() && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { area = fullContentArea(); double total = ((double) area.width()) * ((double) area.height()); // CAPP_WEB_PREPARE_VISIBLE_AREA if (total > MAX_FULL_CONTENT_AREA|| m_drawTransform.isIdentityOrTranslation()) area = visibleContentArea(); } else area = visibleContentArea(); return area; }
void RNAProfileAlignment::getSequenceAlignment(deque<BaseProbs> &baseprob) const { BaseProbs bp; // generate base strings for(size_type i=0;i<size();i++) { if(isBase(i)) { bp.a=label(i).p[ALPHA_PRO_BASE_A]; bp.c=label(i).p[ALPHA_PRO_BASE_C]; bp.g=label(i).p[ALPHA_PRO_BASE_G]; bp.u=label(i).p[ALPHA_PRO_BASE_U]; bp.gap=label(i).p[ALPHA_PRO_GAP]; bp.base=bp.a+bp.c+bp.g+bp.u; baseprob.push_back(bp); } } }
static void initDihedralLUT(void) { /* Backbone */ dihedralP5S3P5S = makeDihedralCache(DIHEDRAL_P_5S3_P_5S); dihedralS3P5S3P = makeDihedralCache(DIHEDRAL_S3_P_5S3_P); /* Everything involving bases */ for (int b = 0; b < NUM_BASE_TYPES; b++) { assert(isBase(b)); switch(b) { case BASE_A: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_A_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_A); break; case BASE_T: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_T_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_T); break; case BASE_C: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_C_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_C); break; case BASE_G: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_G_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_G); break; case BASE_X: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_X_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_X); break; case BASE_Y: dihedralsBasesLUT[b].BS3P5S = makeDihedralCache(DIHEDRAL_Y_S3_P_5S); dihedralsBasesLUT[b].S3P5SB = makeDihedralCache(DIHEDRAL_S3_P_5S_Y); break; default: die("Unknown base type %d in " "initDihedralLUT!\n", b); } } }
static void initAreConnectedLUT(void) { /* Initialize everything to false */ for (int i = 0; i < NUM_PARTICLE_TYPES; i++) { for (int j = 0; j < NUM_PARTICLE_TYPES; j++) { areConnectedLUT[0][i][j] = false; areConnectedLUT[1][i][j] = false; } } /* Everything connected that doesn't involve bases */ areConnectedLUT[0][SUGAR][PHOSPHATE] = true; areConnectedLUT[0][PHOSPHATE][SUGAR] = true; areConnectedLUT[1][PHOSPHATE][SUGAR] = true; /* Everything involving bases */ for (int b = 0; b < NUM_BASE_TYPES; b++) { assert(isBase(b)); /* Base is only connected to sugar on same monomer */ areConnectedLUT[0][b][SUGAR] = true; areConnectedLUT[0][SUGAR][b] = true; } }
double RNAProfileAlignment::bestPairs(size_type node) const { size_type i=node; double d1,d2; WATCH(DBG_GET_PROFILE_STRUCTURE,"RNAProfileForest::getStructureAlignment",node); if(isBase(node)) return 0; else { // node pairs not d1=bestPairs(node+1) + bestPairs(getRightmostBrotherIndex(node+1)); // node pairs d2=label(node).p[ALPHA_PRO_BASEPAIR]; // left path - righthand best pairs i=node+1; while(i < size() && isPair(i)) { d2+=bestPairs(getRightmostBrotherIndex(i+1)); i=i+1; } // right path - lefthand best pairs i=getRightmostBrotherIndex(node+1); while(isPair(i) && i < size()) { d2+=bestPairs(i+1); i=getRightmostBrotherIndex(i+1); } return max(d1,d2); } }
/* Return (the exclusion cut off distance)^2. This is the distance where * the repulsive part of the Lennard Jones potential stops. */ static double getExclusionCutOff2(ParticleType t1, ParticleType t2){ if (isBase(t1) && isBase(t2)) return SQUARE(EXCLUSION_DISTANCE_BASE); else return SQUARE(EXCLUSION_DISTANCE); }
// generate multifasta from fasta file multifasta* read_fasta_file (char* filename) { char ch; // open file FILE *filestream = fopen(filename, "rt"); // if file could not be opened ... if (filestream == NULL) { printf("ERROR: Can not open File %s!\n", filename); return NULL; } // initialize multifasta with 20 entries multifasta* mfast = multifasta_new(20); fasta* seq = NULL; int newline = 1; int header = 0; int sequence = 0; int comment = 0; do { // read current char ch = fgetc (filestream); // check if line just started if (newline) { // check if its just another newline newline = (ch == '\n'); // check if it is a > (header starts) if (ch == '>') { // if header => must not happen if (header) { puts ("ERROR: File is not FASTA (no header after header allowed)!"); // free multifasta, close filestream and return NULL fclose(filestream); multifasta_delete (mfast); return NULL; } // now the header follows header = 1; // is sequence preceeded => finish sequence and add to multifasta if (sequence) { multifasta_add_fasta (mfast, seq); fasta_add_base(seq, '\0'); sequence = 0; } // create new fasta struct seq = fasta_new (MAX_LINE); } // if comment line is starting else if (ch == '#') { comment = 1; } // if a base is the first character else if (isBase(ch)) { // if already a sequence is beeing read => just add base if (sequence) { fasta_add_base(seq, ch); } // else start sequence else { fasta_add_base(seq, ch); sequence = 1; // if no header preceeded => then it's not FASTA if (!header) { puts("ERROR: File is not FASTA (hader missing)!"); // free multifasta, close filestream and return NULL fclose(filestream); multifasta_delete (mfast); return NULL; } header = 0; } } // if no base character within sequence; // empty lines are ok and file may also end else if (!newline && ch != EOF) { // free multifasta, close filestream and return NULL fclose(filestream); printf("ERROR: non-fasta conform line detected! %c is not an allowed symbol!\n", ch); multifasta_delete (mfast); return NULL; } } // if we didn't start a newline else { // check if its a newline character newline = (ch == '\n'); // check if comment and if its a newline => now comment ends // all other chars are ignored (because its a comment) if (comment) { if (newline) { comment = 0; } } // if reading a header else if (header) { // if there is no newline => add it to sequence header if (!newline) fasta_add_header_char(seq, ch); else fasta_add_header_char(seq, '\0'); // do NOT set header = 0 (need for checking correct FASTA) } // thats ok because after a sequence started, there is never (header) else if (sequence) { if (isBase(ch)) fasta_add_base(seq, ch); else if (!newline && ch != EOF) { // free multifasta, close filestream and return NULL fclose(filestream); printf("ERROR: non-fasta conform line detected! %c is not an allowed symbol!\n",ch); multifasta_delete (mfast); return NULL; } } } } while (ch != EOF); // stop if EOF is reached // file may not end with header or without seuqence if (header || !sequence) { puts ("ERROR: File is not FASTA (sequence missing)!"); fclose(filestream); multifasta_delete (mfast); return NULL; } // finish last added sequence multifasta_add_fasta (mfast, seq); fasta_add_base(seq, '\0'); fclose(filestream); return mfast; }
static AngleBaseInfo getAngleBaseInfo(ParticleType base) { assert(isBase(base)); return angleBaseInfoLUT[base]; }
static double getSugarBaseBondDistance(ParticleType base) { assert(isBase(base)); return sugarBaseBondDistanceLUT[base]; }
bool Surface::tryUpdateSurface(Surface* oldSurface) { if (!needsTexture() || !oldSurface->needsTexture()) return false; // merge surfaces based on first layer ID if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId()) return false; m_surfaceBacking = oldSurface->m_surfaceBacking; SkSafeRef(m_surfaceBacking); ALOGV("%p taking old SurfBack %p from surface %p, nt %d", this, m_surfaceBacking, oldSurface, oldSurface->needsTexture()); if (!m_surfaceBacking) { // no SurfBack to inval, so don't worry about it. return true; } SkRegion invalRegion; bool fullInval = false; if (singleLayer() && oldSurface->singleLayer()) { // both are single matching layers, simply apply inval SkRegion* layerInval = getFirstLayer()->getInvalRegion(); invalRegion = *layerInval; if (isBase()) { // the base layer paints outside it's content area to ensure the // viewport is convered, so fully invalidate all tiles if its size // changes to ensure no stale content remains LayerContent* newContent = getFirstLayer()->content(); LayerContent* oldContent = oldSurface->getFirstLayer()->content(); fullInval = newContent->width() != oldContent->width() || newContent->height() != oldContent->height(); } } else { fullInval = m_layers.size() != oldSurface->m_layers.size(); if (!fullInval) { for (unsigned int i = 0; i < m_layers.size(); i++) { if ((m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId()) || (m_layers[i]->fullContentAreaMapped() != oldSurface->m_layers[i]->fullContentAreaMapped())) { // layer list has changed, fully invalidate // TODO: partially invalidate based on layer size/position fullInval = true; break; } else if (!m_layers[i]->getInvalRegion()->isEmpty()) { // merge layer inval - translate the layer's inval region into surface coordinates // TODO: handle scale/3d transform mapping FloatRect layerPos = m_layers[i]->fullContentAreaMapped(); m_layers[i]->getInvalRegion()->translate(layerPos.x(), layerPos.y()); invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op); } } } } if (fullInval) invalRegion.setRect(-1e8, -1e8, 2e8, 2e8); m_surfaceBacking->markAsDirty(invalRegion); return true; }
Color* Surface::background() { if (!isBase() || !m_background.isValid()) return 0; return &m_background; }