std::auto_ptr<OfflineJob> qmimap4::SetLabelOfflineJob::create(InputStream* pStream) { wstring_ptr wstrFolder; READ_STRING(WSTRING, wstrFolder); if (!wstrFolder.get()) return std::auto_ptr<OfflineJob>(0); unsigned int nSize = 0; READ(&nSize, sizeof(nSize)); if (nSize == 0) return std::auto_ptr<OfflineJob>(0); UidList listUid; listUid.resize(nSize); READ(&listUid[0], nSize*sizeof(UidList::value_type)); wstring_ptr wstrLabel; READ_STRING(WSTRING, wstrLabel); unsigned int nLabelSize = 0; READ(&nLabelSize, sizeof(nLabelSize)); LabelList listLabel; listLabel.reserve(nLabelSize); CONTAINER_DELETER(free, listLabel, &freeWString); for (unsigned int n = 0; n < nLabelSize; ++n) { wstring_ptr wstrLabel; READ_STRING(WSTRING, wstrLabel); listLabel.push_back(wstrLabel.release()); } return std::auto_ptr<OfflineJob>(new SetLabelOfflineJob(wstrFolder.get(), listUid, wstrLabel.get(), const_cast<const WCHAR**>(&listLabel[0]), listLabel.size())); }
void QDesignerFormWindowCommand::updateBuddies(QDesignerFormWindowInterface *form, const QString &old_name, const QString &new_name) { QExtensionManager* extensionManager = form->core()->extensionManager(); typedef QList<QLabel*> LabelList; const LabelList label_list = qFindChildren<QLabel*>(form); if (label_list.empty()) return; const QString buddyProperty = QLatin1String("buddy"); const QByteArray oldNameU8 = old_name.toUtf8(); const QByteArray newNameU8 = new_name.toUtf8(); const LabelList::const_iterator cend = label_list.constEnd(); for (LabelList::const_iterator it = label_list.constBegin(); it != cend; ++it ) { if (QDesignerPropertySheetExtension* sheet = qt_extension<QDesignerPropertySheetExtension*>(extensionManager, *it)) { const int idx = sheet->indexOf(buddyProperty); if (idx != -1) { const QByteArray oldBuddy = sheet->property(idx).toByteArray(); if (oldBuddy == oldNameU8) sheet->setProperty(idx, newNameU8); } } } }
/** * @method GetCharSetNames [void:public] * @param names [LabelList&] the vector in which to store the names * * Erases names, then fills names with the names of all stored * character sets. */ void AssumptionsBlock::GetCharSetNames( LabelList& names ) { names.erase( names.begin(), names.end() ); IntSetMap::const_iterator i; for( i = charsets.begin(); i != charsets.end(); i++ ) names.push_back( (*i).first ); }
void quitModule(HINSTANCE hInstance) { RemoveBangCommand("!LabelCreate"); RemoveBangCommand("!LabelDebug"); RemoveBangCommand("!LabelLsBoxHook"); for(LabelListIterator it = labelList.begin(); it != labelList.end(); it++) delete *it; labelList.clear(); SendMessage(GetLitestepWnd(), LM_UNREGISTERMESSAGE, (WPARAM) messageHandler, (LPARAM) lsMessages); DestroyWindow(messageHandler); UnregisterClass("LabelLS", hInstance); UnregisterClass("LabelMessageHandlerLS", hInstance); delete systemInfo; delete defaultSettings; hbmDesktop = (HBITMAP) SelectObject(hdcDesktop, hbmDesktop); DeleteDC(hdcDesktop); DeleteObject(hbmDesktop); }
void X86CodeGen::munchJUMP(Label *lab) { LabelList targets; targets.push_back(lab); assem::OPER *op = _aOPER("jmp", "'j0", NULL, NULL); op->setJumpTargets(targets); emit(op); }
Label *lookupLabel(const string &name) { for(LabelListIterator it = labelList.begin(); it != labelList.end(); it++) { if(_stricmp(name.c_str(), (*it)->getName().c_str()) == 0) return *it; } return 0; }
// Find the label whose buddy the widget is. QLabel *buddyLabelOf(QDesignerFormWindowInterface *fw, QWidget *w) { typedef QList<QLabel*> LabelList; const LabelList labelList = fw->findChildren<QLabel*>(); if (labelList.empty()) return 0; const LabelList::const_iterator cend = labelList.constEnd(); for (LabelList::const_iterator it = labelList.constBegin(); it != cend; ++it ) if ( (*it)->buddy() == w) return *it; return 0; }
void MoMa::SceneApp::draw( LabelList labelList ) { for( int l=0; l<labelList.size(); l++ ) { ofPushStyle(); float labelHue = ofGetStyle().color.getHue(); if( labelList[l].state == UNSELECTED ) { ofColor unselected; unselected.setHsb( labelHue, 128, 255 ); ofSetColor( unselected, 180 ); ofSetLineWidth( 1.2 ); } else if ( labelList[l].state == HOVERED ) { ofColor hovered; hovered.setHsb( labelHue, 180, 255 ); ofSetColor( hovered, 180 ); ofSetLineWidth( 3 ); } else if (labelList[l].state == SELECTED) { ofColor selected; selected.setHsb( labelHue, 240, 255 ); ofSetColor( selected, 200 ); ofSetLineWidth( 3 ); } float labPos = ofMap( labelList[l].idx, idxMin, idxMax, 0, ofGetWidth() ); ofLine( labPos, 0, labPos, ofGetHeight() ); // We draw labels line & names ofDrawBitmapString( labelList[l].name, labPos+6, 14 ); ofPopStyle(); } }
void X86CodeGen::munchEXPR(tree::Exp *exp) { tree::CALL *call; if (_M0(CALL_T, call) == exp) { TempList tsrc; munchArgs(call->args, &tsrc); LabelList targets; targets.push_back(call->func->label); //eax, ecx, edx will be destoryed in c function assem::OPER *op = _aOPER("call", "'j0", frame->registers().callerSaves, tsrc); op->setJumpTargets(targets); emit(op); } }
void StarComponent::drawLabels() { if( m_hideLabels ) return; SkyLabeler *labeler = SkyLabeler::Instance(); labeler->setPen( QColor( KStarsData::Instance()->colorScheme()->colorNamed( "SNameColor" ) ) ); int max = int( m_zoomMagLimit * 10.0 ); if ( max < 0 ) max = 0; if ( max > MAX_LINENUMBER_MAG ) max = MAX_LINENUMBER_MAG; for ( int i = 0; i <= max; i++ ) { LabelList* list = m_labelList[ i ]; for ( int j = 0; j < list->size(); j++ ) { labeler->drawNameLabel( list->at(j).obj, list->at(j).o ); } list->clear(); } }
void BCI2000Viewer::UpdateChannelLabels() { if( mFile.IsOpen() ) { vector<string> signalLabels; if( mFile.Parameters()->Exists( "ChannelNames" ) ) { ParamRef labelParam = mFile.Parameter( "ChannelNames" ); for( int k = 0; k < labelParam->NumValues(); ++k ) signalLabels.push_back( labelParam( k ) ); } for( int i = static_cast<int>( signalLabels.size() ); i < mFile.SignalProperties().Channels(); ++i ) { ostringstream oss; oss << i + 1; signalLabels.push_back( oss.str() ); } LabelList channelLabels; int numMarkerChannels = 0; int j = 1; while( j < ui->channelList->count() && ( ui->channelList->item( j )->flags() & Qt::ItemIsUserCheckable ) ) ++j; int chBase = ++j; for( ; j < ui->channelList->count() && ( ui->channelList->item( j )->flags() & Qt::ItemIsUserCheckable ); ++j ) if( ui->channelList->item( j )->checkState() == Qt::Checked ) channelLabels.push_back( Label( static_cast<int>( channelLabels.size() ), signalLabels[ j - chBase ] ) ); for( int i = 1; i < ui->channelList->count() && ( ui->channelList->item( i )->flags() & Qt::ItemIsUserCheckable ); ++i ) if( ui->channelList->item( i )->checkState() == Qt::Checked ) { channelLabels.push_back( Label( static_cast<int>( channelLabels.size() ), ui->channelList->item( i )->text().toLocal8Bit().constData() ) ); ++numMarkerChannels; } mNumSignalChannels = static_cast<int>( channelLabels.size() ) - numMarkerChannels; ui->signalDisplay->Display().SetNumMarkerChannels( numMarkerChannels ) .SetChannelLabels( channelLabels ) .SetChannelLabelsVisible( true ); } else { mNumSignalChannels = 0; ui->signalDisplay->Display().SetNumMarkerChannels( 0 ) .SetChannelLabels( LabelList() ); } }
void X86CodeGen::munchCJUMP(tree::CJUMP *cj) { tree::CONST *konst; std::string assem; TempList tsrc; const char *cond[] = {"e", "ne", "l", "g", "le", "ge" }; //reverse condition for less or greater const char *cond_r[] = {"e", "ne", "ge", "le", "g", "l" }; bool reverse = false; if (_M0(CONST_T, konst) == cj->l) { assem = format("$%d, 's0", konst->value); tsrc.push_back(munchExp(cj->r)); reverse = true; } else if (_M0(CONST_T, konst) == cj->r) { assem = format("$%d, 's0", konst->value); tsrc.push_back(munchExp(cj->l)); } else { assem = "'s1, 's0"; tsrc.push_back(munchExp(cj->l)); tsrc.push_back(munchExp(cj->r)); } emit(_aOPER("cmpl", assem, TempList(), tsrc)); LabelList targets; targets.push_back(cj->truelab); targets.push_back(cj->falselab); assem = format("j%s", reverse ? cond_r[cj->relop] : cond[cj->relop]); assem::OPER *op = _aOPER(assem, "'j0", NULL, NULL); op->setJumpTargets(targets); emit(op); }
static bool blockify(Shader &shader, const LabelList &labels) { shadir::CodeBlock *activeCodeBlock = nullptr; auto activeBlockList = &shader.blocks; auto labelItr = labels.begin(); Label *label = nullptr; if (labelItr != labels.end()) { label = labelItr->get(); } // Iterate over code and find matching labels to generate code blocks for (auto &ins : shader.code) { bool insertToCode = true; while (label && label->first == ins.get()) { // Most labels will skip current instruction insertToCode = false; if (label->type == Label::LoopStart) { assert(label->linkedLabel); assert(label->linkedLabel->type == Label::LoopEnd); // Save the active block list to the LoopEnd label label->linkedLabel->restoreBlockList = activeBlockList; // Create a new loop block auto loopBlock = new shadir::LoopBlock {}; label->linkedBlock = loopBlock; activeBlockList->emplace_back(loopBlock); // Set the current block list to the loop inner activeBlockList = &loopBlock->inner; activeCodeBlock = nullptr; } else if (label->type == Label::LoopEnd) { assert(label->linkedLabel); assert(label->linkedLabel->type == Label::LoopStart); assert(label->restoreBlockList); // Get the matching LoopBlock from the LoopStart label auto loopBlock = reinterpret_cast<shadir::LoopBlock *>(label->linkedLabel->linkedBlock); // Restore the previous block list activeBlockList = label->restoreBlockList; activeCodeBlock = nullptr; } else if (label->type == Label::ConditionalStart) { assert(label->linkedLabel); assert(label->linkedLabel->type == Label::ConditionalEnd); // Save the active block list to the ConditionalEnd label label->linkedLabel->restoreBlockList = activeBlockList; // Create a new conditional block auto condBlock = new shadir::ConditionalBlock { ins.get() }; label->linkedBlock = condBlock; activeBlockList->emplace_back(condBlock); // Set current block list to the condition inner activeBlockList = &condBlock->inner; activeCodeBlock = nullptr; } else if (label->type == Label::ConditionalElse) { assert(label->linkedLabel); assert(label->linkedLabel->type == Label::ConditionalStart); // Get the matching ConditionalBlock from the ConditionalStart label auto condBlock = reinterpret_cast<shadir::ConditionalBlock *>(label->linkedLabel->linkedBlock); // Set current block list to the condition else activeBlockList = &condBlock->innerElse; activeCodeBlock = nullptr; } else if (label->type == Label::ConditionalEnd) { assert(label->linkedLabel); assert(label->linkedLabel->type == Label::ConditionalStart); assert(label->restoreBlockList); // Get the matching ConditionalBlock from the ConditionalStart label auto condBlock = reinterpret_cast<shadir::ConditionalBlock *>(label->linkedLabel->linkedBlock); // Restore the previous block list activeBlockList = label->restoreBlockList; activeCodeBlock = nullptr; // Do not skip the current instruction, add it to a code block insertToCode = true; } // Start comparing to next label! ++labelItr; if (labelItr != labels.end()) { label = labelItr->get(); } else { label = nullptr; } } if (insertToCode) { assert(activeBlockList); if (!activeCodeBlock) { // Create a new block for active list activeCodeBlock = new shadir::CodeBlock {}; activeBlockList->emplace_back(activeCodeBlock); } activeCodeBlock->code.push_back(ins.get()); } } return true; }
LRESULT WINAPI MessageHandlerProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case LM_GETREVID: { UINT uLength; StringCchPrintf((char*)lParam, 64, "%s %s", V_NAME, V_VERSION); if (SUCCEEDED(StringCchLength((char*)lParam, 64, &uLength))) return uLength; lParam = NULL; return 0; } case LM_REFRESH: { StringList labelNames = GetRCNameList("Labels"); // refresh the "AllLabels" configuration delete defaultSettings; defaultSettings = new LabelSettings(); for(LabelListIterator iter = labelList.begin(); iter != labelList.end(); iter++) { if(!(*iter)->getBox()) { // destroy all labels that no longer exist and that are not in a box for(StringListIterator it = labelNames.begin(); it != labelNames.end(); it++) { if(_stricmp((*it).c_str(), (*iter)->getName().c_str()) == 0) break; } if (it == labelNames.end()) { labelList.remove(*iter); delete *iter; continue; } } // we can reconfigure all other labels, even if they are "boxed" (*iter)->reconfigure(); } // create the rest for(StringListIterator it = labelNames.begin(); it != labelNames.end(); it++) { Label *label = lookupLabel(*it); if (!label) { label = new Label(*it); label->load(hInstance); labelList.insert(labelList.end(), label); } } return 0; } case LM_UPDATEBG: { PaintDesktopEx(0, 0, 0, 0, 0, 0, 0, TRUE); for(LabelListIterator i = labelList.begin(); i != labelList.end(); i++) { Label *label = *i; if(label->getBox() == 0) label->repaint(true); } return 0; } case WM_DISPLAYCHANGE: case WM_SETTINGCHANGE: { PostMessage(hWnd, LM_UPDATEBG, 0, 0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }
void AverageDisplay::Initialize( const SignalProperties&, const SignalProperties& ) { for( size_t i = 0; i < mVisualizations.size(); ++i ) mVisualizations[ i ].Send( CfgID::Visible, false ); mVisualizations.clear(); mChannelIndices.clear(); mPowerSums.clear(); mTargetCodes.clear(); mSignalOfCurrentRun.clear(); #ifdef SET_BASELINE mBaselines.clear(); mBaselineSamples.clear(); #endif // SET_BASELINE LabelList markerLabels; for( int i = 0; i < Parameter( "AvgDisplayMarkers" )->NumRows(); ++i ) { string markerName = Parameter( "AvgDisplayMarkers" )( i, 0 ); int position = MeasurementUnits::ReadAsTime( OptionalParameter( markerName, -1 ) ) * Parameter( "SampleBlockSize" ); if( position >= 0 ) markerLabels.push_back( Label( position, markerName ) ); } int numChannels = Parameter( "AvgDisplayCh" )->NumRows(); mPowerSums.resize( maxPower + 1, vector<vector<vector<float> > >( numChannels ) ); for( int i = 0; i < numChannels; ++i ) { ostringstream oss; oss << "AVG" << i; mVisualizations.push_back( GenericVisualization( oss.str() ) ); GenericVisualization& vis = mVisualizations[ i ]; string windowTitle = Parameter( "AvgDisplayCh" )( i, 1 ); if( windowTitle == "" ) windowTitle = "unknown"; windowTitle += " Average"; vis.Send( CfgID::WindowTitle, windowTitle ); // Note min and max value are interchanged to account for EEG display direction. vis.Send( CfgID::MinValue, int( Parameter( "AvgDisplayMin" ) ) ); vis.Send( CfgID::MaxValue, int( Parameter( "AvgDisplayMax" ) ) ); vis.Send( CfgID::NumSamples, 0 ); vis.Send( CfgID::GraphType, CfgID::Polyline ); if( !markerLabels.empty() ) vis.Send( CfgID::XAxisMarkers, markerLabels ); ColorList channelColors( sChannelColors ); vis.Send( CfgID::ChannelColors, channelColors ); vis.Send( CfgID::ChannelGroupSize, 0 ); vis.Send( CfgID::ShowBaselines, 1 ); vis.Send( CfgID::Visible, true ); mChannelIndices.push_back( Parameter( "AvgDisplayCh" )( i, 0 ) - 1 ); } mSignalOfCurrentRun.resize( numChannels ); #ifdef SET_BASELINE mBaselines.resize( numChannels ); mBaselineSamples.resize( numChannels ); #endif // SET_BASELINE mLastTargetCode = 0; }
void AverageDisplay::Process( const GenericSignal& Input, GenericSignal& Output ) { size_t targetCode = State( "TargetCode" ); if( targetCode == 0 && targetCode != mLastTargetCode ) { size_t targetIndex = find( mTargetCodes.begin(), mTargetCodes.end(), mLastTargetCode ) - mTargetCodes.begin(); if( targetIndex == mTargetCodes.size() ) mTargetCodes.push_back( mLastTargetCode ); // End of the current target code run. for( size_t i = 0; i < mChannelIndices.size(); ++i ) { for( int power = 0; power <= maxPower; ++power ) { // - If the target code occurred for the first time, adapt the power sums. if( mPowerSums[ power ][ i ].size() <= targetIndex ) mPowerSums[ power ][ i ].resize( targetIndex + 1 ); // - Update power sum sizes. if( mPowerSums[ power ][ i ][ targetIndex ].size() < mSignalOfCurrentRun[ i ].size() ) mPowerSums[ power ][ i ][ targetIndex ].resize( mSignalOfCurrentRun[ i ].size(), 0 ); } #ifdef SET_BASELINE if( mBaselineSamples[ i ] > 0 ) mBaselines[ i ] /= mBaselineSamples[ i ]; #endif // SET_BASELINE // - Compute the power sum entries. for( size_t j = 0; j < mSignalOfCurrentRun[ i ].size(); ++j ) { #ifdef SET_BASELINE mSignalOfCurrentRun[ i ][ j ] -= mBaselines[ i ]; #endif // SET_BASELINE float summand = 1.0; for( size_t power = 0; power < maxPower; ++power ) { mPowerSums[ power ][ i ][ targetIndex ][ j ] += summand; summand *= mSignalOfCurrentRun[ i ][ j ]; } mPowerSums[ maxPower ][ i ][ targetIndex ][ j ] += summand; } } // - Clear target run buffer. for( size_t i = 0; i < mSignalOfCurrentRun.size(); ++i ) mSignalOfCurrentRun[ i ].clear(); #ifdef SET_BASELINE for( size_t i = 0; i < mBaselines.size(); ++i ) { mBaselineSamples[ i ] = 0; mBaselines[ i ] = 0; } #endif // SET_BASELINE // - Compute and display the averages. for( size_t channel = 0; channel < mVisualizations.size(); ++channel ) { size_t numTargets = mPowerSums[ maxPower ][ channel ].size(), numSamples = numeric_limits<size_t>::max(); for( size_t target = 0; target < numTargets; ++target ) if( mPowerSums[ maxPower ][ channel ][ target ].size() < numSamples ) numSamples = mPowerSums[ maxPower ][ channel ][ target ].size(); // To minimize user confusion, always send target averages in ascending order // of target codes. This ensures that colors in the display don't depend // on the order of target codes in the task sequence once all target codes // occurred. // We cannot, however, avoid color changes when yet unknown target codes // occur. // // The map is automatically sorted by its "key", so all we need to do // is to put the target codes and their indices into it, using the // target code as "key" and the index as "value", and later iterate over // the map to get the indices sorted by their associated target code. map<int, int> targetCodesToIndex; for( size_t target = 0; target < numTargets; ++target ) targetCodesToIndex[ mTargetCodes[ target ] ] = target; GenericSignal average( numTargets, numSamples ); LabelList labels; for( map<int, int>::const_iterator target = targetCodesToIndex.begin(); target != targetCodesToIndex.end(); ++target ) { for( size_t sample = 0; sample < numSamples; ++sample ) // If everything behaves as we believe it will, // a division by zero is impossible. // If it occurs nevertheless, the logic is messed up. average( target->second, sample ) = mPowerSums[ 1 ][ channel ][ target->second ][ sample ] / mPowerSums[ 0 ][ channel ][ target->second ][ sample ]; ostringstream oss; oss << "Target " << target->first; string targetName = OptionalParameter( "TargetNames", target->first ); if( targetName != "" ) oss << " (" << targetName << ")"; labels.push_back( Label( target->second, oss.str() ) ); } mVisualizations[ channel ].Send( CfgID::ChannelLabels, labels ); ostringstream oss; oss << ( Parameter( "SampleBlockSize" ) / Input.Elements() / Parameter( "SamplingRate" ) ) << "s"; mVisualizations[ channel ].Send( CfgID::SampleUnit, oss.str() ); mVisualizations[ channel ].Send( average ); } } if( targetCode != 0 ) { // Store the current signal to the end of the run buffer. for( size_t i = 0; i < mChannelIndices.size(); ++i ) { size_t signalCursorPos = mSignalOfCurrentRun[ i ].size(); mSignalOfCurrentRun[ i ].resize( signalCursorPos + Input.Elements() ); for( int j = 0; j < Input.Elements(); ++j ) mSignalOfCurrentRun[ i ][ signalCursorPos + j ] = Input( mChannelIndices[ i ], j ); } #ifdef SET_BASELINE if( OptionalState( "BaselineInterval" ) || OptionalState( "Baseline" ) ) { for( size_t i = 0; i < mChannelIndices.size(); ++i ) { mBaselineSamples[ i ] += Input.Elements(); for( int j = 0; j < Input.Elements(); ++j ) mBaselines[ i ] += Input( mChannelIndices[ i ], j ); } } #endif // SET_BASELINE } mLastTargetCode = targetCode; Output = Input; }
void RadialMap::Widget::paintExplodedLabels(QPainter &paint) const { //we are a friend of RadialMap::Map LabelList list; list.setAutoDelete(true); Q3PtrListIterator<Label> it(list); unsigned int startLevel = 0; //1. Create list of labels sorted in the order they will be rendered if (m_focus && m_focus->file() != m_tree) //separate behavior for selected vs unselected segments { //don't bother with files if (m_focus->file() && !m_focus->file()->isDirectory()) return; //find the range of levels we will be potentially drawing labels for //startLevel is the level above whatever m_focus is in for (const Directory *p = (const Directory*)m_focus->file(); p != m_tree; ++startLevel) p = p->parent(); //range=2 means 2 levels to draw labels for unsigned int a1, a2, minAngle; a1 = m_focus->start(); a2 = m_focus->end(); //boundry angles minAngle = int(m_focus->length() * LABEL_MIN_ANGLE_FACTOR); #define segment (*it) #define ring (m_map.m_signature + i) //**** Levels should be on a scale starting with 0 //**** range is a useless parameter //**** keep a topblock var which is the lowestLevel OR startLevel for identation purposes for (unsigned int i = startLevel; i <= m_map.m_visibleDepth; ++i) for (Iterator<Segment> it = ring->iterator(); it != ring->end(); ++it) if (segment->start() >= a1 && segment->end() <= a2) if (segment->length() > minAngle) list.inSort(new Label(segment, i)); #undef ring #undef segment } else { #define ring m_map.m_signature for (Iterator<Segment> it = ring->iterator(); it != ring->end(); ++it) if ((*it)->length() > 288) list.inSort(new Label((*it), 0)); #undef ring } //2. Check to see if any adjacent labels are too close together // if so, remove the least significant labels it.toFirst(); Q3PtrListIterator<Label> jt(it); ++jt; while (jt) //**** no need to check _it_ as jt will be NULL if _it_ was too { //this method is fairly efficient if ((*it)->tooClose((*jt)->a)) { if ((*it)->lvl > (*jt)->lvl) { list.remove(*it); it = jt; } else list.remove(*jt); } else ++it; jt = it; ++jt; } //used in next two steps bool varySizes; //**** should perhaps use doubles int *sizes = new int [ m_map.m_visibleDepth + 1 ]; //**** make sizes an array of floats I think instead (or doubles) do { //3. Calculate font sizes { //determine current range of levels to draw for uint range = 0; for (it.toFirst(); it != 0; ++it) { uint lvl = (*it)->lvl; if (lvl > range) range = lvl; //**** better way would just be to assign if nothing is range } range -= startLevel; //range 0 means 1 level of labels varySizes = Config::varyLabelFontSizes && (range != 0); if (varySizes) { //create an array of font sizes for various levels //will exceed normal font pitch automatically if necessary, but not minPitch //**** this needs to be checked lots //**** what if this is negative (min size gtr than default size) uint step = (paint.font().pointSize() - Config::minFontPitch) / range; if (step == 0) step = 1; for (uint x = range + startLevel, y = Config::minFontPitch; x >= startLevel; y += step, --x) sizes[x] = y; } } //4. determine label co-ordinates int x1, y1, x2, y2, x3, tx, ty; //coords double sinra, cosra, ra; //angles int cx = m_map.width() / 2 + m_offset.x(); //centre relative to canvas int cy = m_map.height() / 2 + m_offset.y(); int spacer, preSpacer = int(m_map.m_ringBreadth * 0.5) + m_map.m_innerRadius; int fullStrutLength = (m_map.width() - m_map.MAP_2MARGIN) / 2 + LABEL_MAP_SPACER; //full length of a strut from map center int prevLeftY = 0; int prevRightY = height(); bool rightSide; QFont font; for (it.toFirst(); it != 0; ++it) { //** bear in mind that text is drawn with QPoint param as BOTTOM left corner of text box QString qs = (*it)->segment->file()->name(); if (varySizes) font.setPointSize(sizes[(*it)->lvl]); QFontMetrics fm(font); int fmh = fm.height(); //used to ensure label texts don't overlap int fmhD4 = fmh / 4; fmh += LABEL_TEXT_VMARGIN; rightSide = ((*it)->a < 1440 || (*it)->a > 4320); ra = M_PI/2880 * (*it)->a; //convert to radians sincos(ra, &sinra, &cosra); spacer = preSpacer + m_map.m_ringBreadth * (*it)->lvl; x1 = cx + (int)(cosra * spacer); y1 = cy - (int)(sinra * spacer); y2 = y1 - (int)(sinra * (fullStrutLength - spacer)); if (rightSide) { //righthand side, going upwards if (y2 > prevRightY /*- fmh*/) //then it is too low, needs to be drawn higher y2 = prevRightY /*- fmh*/; } else //lefthand side, going downwards if (y2 < prevLeftY/* + fmh*/) //then we're too high, need to be drawn lower y2 = prevLeftY /*+ fmh*/; x2 = x1 - int(double(y2 - y1) / tan(ra)); ty = y2 + fmhD4; if (rightSide) { if (x2 > width() || ty < fmh || x2 < x1) { //skip this strut //**** don't duplicate this code list.remove(*it); //will delete the label and set it to list.current() which _should_ be the next ptr break; } prevRightY = ty - fmh - fmhD4; //must be after above's "continue" qs = fm.elidedText(qs, Qt::ElideMiddle, width() - x2); x3 = width() - fm.width(qs) - LABEL_HMARGIN //outer margin - LABEL_TEXT_HMARGIN //margin between strut and text //- ((*it)->lvl - startLevel) * LABEL_HMARGIN; //indentation ; if (x3 < x2) x3 = x2; tx = x3 + LABEL_TEXT_HMARGIN; } else { if (x2 < 0 || ty > height() || x2 > x1) { //skip this strut list.remove(*it); //will delete the label and set it to list.current() which _should_ be the next ptr break; } prevLeftY = ty + fmh - fmhD4; qs = fm.elidedText(qs, Qt::ElideMiddle, x2); //**** needs a little tweaking: tx = fm.width(qs) + LABEL_HMARGIN/* + ((*it)->lvl - startLevel) * LABEL_HMARGIN*/; if (tx > x2) { //text is too long tx = LABEL_HMARGIN + x2 - tx; //some text will be lost from sight x3 = x2; //no text margin (right side of text here) } else { x3 = tx + LABEL_TEXT_HMARGIN; tx = LABEL_HMARGIN /*+ ((*it)->lvl - startLevel) * LABEL_HMARGIN*/; } } (*it)->x1 = x1; (*it)->y1 = y1; (*it)->x2 = x2; (*it)->y2 = y2; (*it)->x3 = x3; (*it)->tx = tx; (*it)->ty = ty; (*it)->qs = qs; } //if an element is deleted at this stage, we need to do this whole //iteration again, thus the following loop //**** in rare case that deleted label was last label in top level // and last in labelList too, this will not work as expected (not critical) } while (it != 0); //5. Render labels paint.setPen(QPen(Qt::black, 1)); for (it.toFirst(); it != 0; ++it) { if (varySizes) { //**** how much overhead in making new QFont each time? // (implicate sharing remember) QFont font = paint.font(); font.setPointSize(sizes[(*it)->lvl]); paint.setFont(font); } paint.drawEllipse((*it)->x1 - 3, (*it)->y1 - 3, 7, 7); //**** CPU intensive! better to use a pixmap paint.drawLine((*it)->x1, (*it)->y1, (*it)->x2, (*it)->y2); paint.drawLine((*it)->x2, (*it)->y2, (*it)->x3, (*it)->y2); paint.drawText((*it)->tx, (*it)->ty, (*it)->qs); } delete [] sizes; }
static bool labelify(Shader &shader, LabelList &labels) { std::stack<shadir::CfInstruction *> loopStarts; // LOOP_START* std::stack<shadir::CfInstruction *> pushes; // PUSH std::stack<shadir::CfInstruction *> pops; // POP* std::stack<shadir::AluInstruction *> predSets; // PRED_SET* // Iterate over the code and find matching code patterns to labelify for (auto itr = shader.code.begin(); itr != shader.code.end(); ++itr) { auto &ins = *itr; if (ins->insType == shadir::Instruction::ControlFlow) { auto cfIns = reinterpret_cast<shadir::CfInstruction*>(ins.get()); if (cfIns->id == latte::cf::inst::LOOP_START || cfIns->id == latte::cf::inst::LOOP_START_DX10 || cfIns->id == latte::cf::inst::LOOP_START_NO_AL) { // Found a loop start, find a matching loop_end in the correct stack loopStarts.push(cfIns); } else if (cfIns->id == latte::cf::inst::LOOP_END) { assert(loopStarts.size()); // Create a LoopStart label auto labelStart = new Label { Label::LoopStart, loopStarts.top() }; loopStarts.pop(); labels.emplace_back(labelStart); // Create a LoopEnd label auto labelEnd = new Label { Label::LoopEnd, ins.get() }; labels.emplace_back(labelEnd); // Link the start and end labels labelEnd->linkedLabel = labelStart; labelStart->linkedLabel = labelEnd; } else if (cfIns->id == latte::cf::inst::LOOP_CONTINUE || cfIns->id == latte::cf::inst::LOOP_BREAK) { assert(loopStarts.size()); assert(predSets.size()); // Create a ConditionalStart label for the last PRED_SET auto labelStart = new Label { Label::ConditionalStart, predSets.top() }; predSets.pop(); labels.emplace_back(labelStart); // Create a ConditionalEnd label for after the BREAK/CONTINUE instruction auto labelEnd = new Label { Label::ConditionalEnd, (itr + 1)->get() }; labels.emplace_back(labelEnd); // Link the start and end labels labelEnd->linkedLabel = labelStart; labelStart->linkedLabel = labelEnd; } else if (cfIns->id == latte::cf::inst::JUMP) { assert(predSets.size()); assert(pushes.size()); // Find the end of the jump auto jumpEnd = std::find_if(itr, shader.code.end(), [cfIns](auto &ins) { return ins->cfPC == cfIns->addr; }); assert(jumpEnd != shader.code.end()); // Check if this jump has an ELSE branch auto jumpElse = shader.code.end(); if ((*jumpEnd)->insType == shadir::Instruction::ControlFlow) { auto jumpEndCfIns = reinterpret_cast<shadir::CfInstruction*>(jumpEnd->get()); if (jumpEndCfIns->id == latte::cf::inst::ELSE) { jumpElse = jumpEnd; // Find the real end of the jump jumpEnd = std::find_if(jumpElse, shader.code.end(), [jumpEndCfIns](auto &ins) { return ins->cfPC == jumpEndCfIns->addr; }); assert(jumpEnd != shader.code.end()); } } // Create a conditional start label auto labelStart = new Label { Label::ConditionalStart, predSets.top() }; predSets.pop(); labels.emplace_back(labelStart); // Create a conditional else label, if needed if (jumpElse != shader.code.end()) { auto labelElse = new Label { Label::ConditionalElse, jumpElse->get() }; labelElse->linkedLabel = labelStart; labels.emplace_back(labelElse); } // Create a conditional end label auto labelEnd = new Label { Label::ConditionalEnd, jumpEnd->get() }; labels.emplace_back(labelEnd); // Eliminate our JUMP instruction labels.emplace_back(new Label { Label::Eliminated, ins.get() }); // Link start and end labels labelEnd->linkedLabel = labelStart; labelStart->linkedLabel = labelEnd; } else if (cfIns->id == latte::cf::inst::PUSH) { pushes.push(cfIns); } else if (cfIns->id == latte::cf::inst::POP) { pops.push(cfIns); } } else if (ins->insType == shadir::Instruction::ALU) { auto aluIns = reinterpret_cast<shadir::AluInstruction *>(ins.get()); if (aluIns->opType == latte::alu::Encoding::OP2) { auto &opcode = latte::alu::op2info[aluIns->op2]; if (opcode.flags & latte::alu::Opcode::PredSet) { predSets.push(aluIns); } } } } // Lets be sure we consumed everything we are interested in! assert(loopStarts.size() == 0); assert(predSets.size() == 0); // Sort the labels std::sort(labels.begin(), labels.end(), [](auto &lhs, auto &rhs) { if (lhs->first->cfPC == rhs->first->cfPC) { assert(lhs->linkedLabel && rhs->linkedLabel); auto lhsLinkedPC = lhs->linkedLabel->first->cfPC; auto rhsLinkedPC = rhs->linkedLabel->first->cfPC; if (lhsLinkedPC < lhs->first->cfPC) { if (rhsLinkedPC < rhs->first->cfPC) { return lhsLinkedPC > rhsLinkedPC; } else { return true; } } else { return false; } } return lhs->first->cfPC < rhs->first->cfPC; }); return true; }
int initModuleEx(HWND hParent, HINSTANCE hInstance, const char *lsPath) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_GLOBALCLASS | CS_DBLCLKS; wc.lpfnWndProc = Label::windowProcedure; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(Label *); wc.hInstance = hInstance; wc.hbrBackground = 0; wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = 0; wc.lpszMenuName = 0; wc.lpszClassName = "LabelLS"; wc.hIconSm = 0; RegisterClassEx(&wc); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_GLOBALCLASS; wc.lpfnWndProc = MessageHandlerProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hbrBackground = 0; wc.hCursor = 0; wc.hIcon = 0; wc.lpszMenuName = 0; wc.lpszClassName = "LabelMessageHandlerLS"; wc.hIconSm = 0; RegisterClassEx(&wc); messageHandler = CreateWindowEx(WS_EX_TOOLWINDOW, "LabelMessageHandlerLS", 0, WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, 0); if (!messageHandler) return 1; SendMessage(GetLitestepWnd(), LM_REGISTERMESSAGE, (WPARAM) messageHandler, (LPARAM) lsMessages); ::hInstance = hInstance; defaultSettings = new LabelSettings(); systemInfo = new SystemInfo(); StringList labelNames = GetRCNameList("Labels"); labelNames.merge(GetRCNameList("Label")); // if(labelNames.empty()) labelNames.insert(labelNames.end(), "Label"); for(StringListIterator it = labelNames.begin(); it != labelNames.end(); it++) { if(GetRCBoolean(*it, "LSBoxName")) continue; Label *label = new Label(*it); label->load(hInstance); labelList.insert(labelList.end(), label); } AddBangCommand("!LabelCreate", CreateLabelBangCommand); AddBangCommand("!LabelDebug", DebugBangCommand); //LsBox Support - blkhawk AddBangCommand("!LabelLsBoxHook", LsBoxHookBangCommand); return 0; }