bool HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) { #if DEBUG_SHOW_WINDING SkOpContour::debugShowWindingValues(contourList); #endif CoincidenceCheck(contourList, total); #if DEBUG_SHOW_WINDING SkOpContour::debugShowWindingValues(contourList); #endif fixOtherTIndex(contourList); checkEnds(contourList); // check if connecting curve intersected at the same end bool hasM = checkMultiples(contourList); // check if intersections agree on t and point values SkTDArray<SkOpSegment::AlignedSpan> aligned; if (hasM) { alignMultiples(contourList, &aligned); // align pairs of identical points alignCoincidence(contourList, aligned); } checkDuplicates(contourList); // check if spans have the same number on the other end checkTiny(contourList); // if pair have the same end points, mark them as parallel checkSmall(contourList); // a pair of curves with a small span may turn into coincident lines joinCoincidence(contourList); // join curves that connect to a coincident pair sortSegments(contourList); if (!calcAngles(contourList)) { return false; } sortAngles(contourList); #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY DebugShowActiveSpans(*contourList); #endif return true; }
static void handleTick(struct tm *tick_time, TimeUnits units_changed) { calcAngles(tick_time); if (units_changed & DAY_UNIT) { setDate(tick_time); } layer_mark_dirty(layer); }
bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidence, SkChunkAlloc* allocator) { SkOpGlobalState* globalState = contourList->globalState(); // combine t values when multiple intersections occur on some segments but not others moveMultiples(contourList); findCollapsed(contourList); // move t values and points together to eliminate small/tiny gaps moveNearby(contourList); align(contourList); // give all span members common values coincidence->fixAligned(); // aligning may have marked a coincidence pt-t deleted #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kIntersecting); #endif // look for intersections on line segments formed by moving end points addAlignIntersections(contourList, allocator); coincidence->addMissing(allocator); #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kWalking); #endif // check to see if, loosely, coincident ranges may be expanded if (coincidence->expand()) { coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(globalState)); } // the expanded ranges may not align -- add the missing spans coincidence->mark(); // mark spans of coincident segments as coincident // look for coincidence missed earlier if (missingCoincidence(contourList, coincidence, allocator)) { (void) coincidence->expand(); coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(globalState)); coincidence->mark(); } SkOpCoincidence overlaps; do { SkOpCoincidence* pairs = overlaps.isEmpty() ? coincidence : &overlaps; if (!pairs->apply()) { // adjust the winding value to account for coincident edges return false; } // For each coincident pair that overlaps another, when the receivers (the 1st of the pair) // are different, construct a new pair to resolve their mutual span pairs->findOverlaps(&overlaps, allocator); } while (!overlaps.isEmpty()); calcAngles(contourList, allocator); sortAngles(contourList); if (globalState->angleCoincidence()) { (void) missingCoincidence(contourList, coincidence, allocator); if (!coincidence->apply()) { return false; } } #if DEBUG_ACTIVE_SPANS coincidence->debugShowCoincidence(); DebugShowActiveSpans(contourList); #endif return true; }
static void init(void) { time_t t; struct tm *tm; initRadiuses(); readConfig(); app_message_init(); window = window_create(); window_set_background_color(window, GColorBlack); window_stack_push(window, false); rootLayer = window_get_root_layer(window); t = time(NULL); tm = localtime(&t); layer = layer_create(GRect(0, 0, 144, 168)); layer_set_update_proc(layer, updateScreen); layer_add_child(rootLayer, layer); font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_TIMEBURNER_20)); textFrame = GRect(72-innerCircleInnerRadius, 60, 2*innerCircleInnerRadius, 60); textLayer = text_layer_create(textFrame); text_layer_set_text_alignment(textLayer, GTextAlignmentCenter); text_layer_set_overflow_mode(textLayer, GTextOverflowModeWordWrap); text_layer_set_background_color(textLayer, GColorClear); text_layer_set_text_color(textLayer, GColorWhite); text_layer_set_font(textLayer, font); layer_set_hidden(text_layer_get_layer(textLayer), true); layer_add_child(rootLayer, text_layer_get_layer(textLayer)); setDate(tm); calcAngles(tm); tick_timer_service_subscribe(MINUTE_UNIT, handleTick); accel_tap_service_subscribe(tapHandler); bluetooth_connection_service_subscribe(&handle_bluetooth); }
bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidence) { SkOpGlobalState* globalState = contourList->globalState(); DEBUG_COINCIDENCE_HEALTH(contourList, "start"); #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kIntersecting); #endif // match up points within the coincident runs if (!coincidence->addExpanded()) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "addExpanded"); #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kWalking); #endif // combine t values when multiple intersections occur on some segments but not others if (!moveMultiples(contourList)) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "moveMultiples"); // move t values and points together to eliminate small/tiny gaps (void) moveNearby(contourList); DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby"); #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kIntersecting); #endif // add coincidence formed by pairing on curve points and endpoints coincidence->correctEnds(); if (!coincidence->addEndMovedSpans()) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "addEndMovedSpans"); const int SAFETY_COUNT = 100; // FIXME: tune int safetyHatch = SAFETY_COUNT; // look for coincidence present in A-B and A-C but missing in B-C while (coincidence->addMissing()) { if (!--safetyHatch) { SkASSERT(0); // FIXME: take this out after verifying std tests don't trigger return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "addMissing"); moveNearby(contourList); DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby"); } DEBUG_COINCIDENCE_HEALTH(contourList, "addMissing2"); // FIXME: only call this if addMissing modified something when returning false moveNearby(contourList); DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby2"); // check to see if, loosely, coincident ranges may be expanded if (coincidence->expand()) { DEBUG_COINCIDENCE_HEALTH(contourList, "expand1"); coincidence->addMissing(); DEBUG_COINCIDENCE_HEALTH(contourList, "addMissing2"); if (!coincidence->addExpanded()) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "addExpanded2"); if (!moveMultiples(contourList)) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "moveMultiples2"); moveNearby(contourList); } #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kWalking); #endif DEBUG_COINCIDENCE_HEALTH(contourList, "expand2"); // the expanded ranges may not align -- add the missing spans if (!coincidence->addExpanded()) { SkASSERT(globalState->debugSkipAssert()); return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "addExpanded3"); coincidence->correctEnds(); if (!coincidence->mark()) { // mark spans of coincident segments as coincident return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "mark1"); // look for coincidence lines and curves undetected by intersection if (missingCoincidence(contourList)) { #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kIntersecting); #endif DEBUG_COINCIDENCE_HEALTH(contourList, "missingCoincidence1"); (void) coincidence->expand(); DEBUG_COINCIDENCE_HEALTH(contourList, "expand3"); if (!coincidence->addExpanded()) { return false; } #if DEBUG_VALIDATE globalState->setPhase(SkOpGlobalState::kWalking); #endif DEBUG_COINCIDENCE_HEALTH(contourList, "addExpanded3"); if (!coincidence->mark()) { return false; } } else { DEBUG_COINCIDENCE_HEALTH(contourList, "missingCoincidence2"); (void) coincidence->expand(); } DEBUG_COINCIDENCE_HEALTH(contourList, "missingCoincidence3"); (void) coincidence->expand(); #if 0 // under development // coincident runs may cross two or more spans, but the opposite spans may be out of order if (!coincidence->reorder()) { return false; } #endif DEBUG_COINCIDENCE_HEALTH(contourList, "coincidence.reorder"); SkOpCoincidence overlaps(globalState); do { SkOpCoincidence* pairs = overlaps.isEmpty() ? coincidence : &overlaps; if (!pairs->apply()) { // adjust the winding value to account for coincident edges return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->apply"); // For each coincident pair that overlaps another, when the receivers (the 1st of the pair) // are different, construct a new pair to resolve their mutual span if (!pairs->findOverlaps(&overlaps)) { return false; } DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->findOverlaps"); } while (!overlaps.isEmpty()); calcAngles(contourList); sortAngles(contourList); if (globalState->angleCoincidence()) { (void) missingCoincidence(contourList); if (!coincidence->apply()) { return false; } } #if DEBUG_COINCIDENCE_VERBOSE coincidence->debugShowCoincidence(); #endif #if DEBUG_COINCIDENCE coincidence->debugValidate(); #endif SkPathOpsDebug::ShowActiveSpans(contourList); return true; }