Browse Source

Refactor the C code part.

txlyre 10 months ago
parent
commit
27af14af97
4 changed files with 54 additions and 35 deletions
  1. 24 26
      counter.c/counter.c
  2. 1 2
      counter.c/counter.h
  3. 1 7
      counter.c/main.c
  4. 28 0
      counter.c/powers_table.h

+ 24 - 26
counter.c/counter.c

@@ -2,45 +2,43 @@
 #include <stdio.h>
 #include <cairo/cairo.h>
 #include "counter.h"
+#include "powers_table.h"
 
 static cairo_surface_t *digits[10];
 
-void counter_init(void) {
+void counter_release(void) {
+  for (int i = 0; i < 10; i++)
+    if (digits[i])
+      cairo_surface_destroy(digits[i]);
+}
+
+static cairo_surface_t *get_digit(int digit) {
+  cairo_surface_t *surface;
   char buffer[16];
 
-  for (int i = 0; i < 10; i++) {
-    snprintf(buffer, sizeof(buffer), "./images/%d.png", i);
+  surface = digits[digit];
+
+  if (surface == NULL) {
+    snprintf(buffer, sizeof(buffer), "./images/%d.png", digit);
 
-    digits[i] = cairo_image_surface_create_from_png(buffer);
+    surface = digits[digit] = cairo_image_surface_create_from_png(buffer);
   }
-}
 
-void counter_release(void) {
-  for (int i = 0; i < 10; i++)
-    cairo_surface_destroy(digits[i]);
+  return surface;
 }
 
-static int count_digits(int number) {
-  if (number < 10) return 1;
-  if (number < 100) return 2;
-  if (number < 1000) return 3;
-  if (number < 10000) return 4;
-  if (number < 100000) return 5;
-  if (number < 1000000) return 6;
-  if (number < 10000000) return 7;
-  if (number < 100000000) return 8;
-  if (number < 1000000000) return 9;
-
-  return 10;
-}
+static int count_digits(unsigned long number) {
+  for (int i = 1; i < POWERS_COUNT; i++)
+    if (number < powers_table[i][0]) return powers_table[i][1];
 
-static int powersof10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
+  return powers_table[POWERS_COUNT-1][1];
+}
 
-static int nth_digit(int number, int n) {
-  return (number / powersof10[n]) % 10;
+static int nth_digit(unsigned long number, int n) {
+  return (number / powers_table[n][0]) % 10;
 }
 
-void counter_create(int number, char *filename) {
+void counter_create(unsigned long number, char *filename) {
   int digits_count;
   cairo_surface_t *surface;
   cairo_t *cr;
@@ -50,7 +48,7 @@ void counter_create(int number, char *filename) {
   cr = cairo_create(surface);
  
   for (int i = 0; i < digits_count; i++) {
-    cairo_set_source_surface(cr, digits[nth_digit(number, digits_count-1-i)], i * DIGIT_WIDTH, 0);
+    cairo_set_source_surface(cr, get_digit(nth_digit(number, digits_count-1-i)), i * DIGIT_WIDTH, 0);
     cairo_paint(cr);
   }
 

+ 1 - 2
counter.c/counter.h

@@ -4,8 +4,7 @@
 #define DIGIT_WIDTH  68
 #define DIGIT_HEIGHT 150
 
-void counter_init(void);
 void counter_release(void);
-void counter_create(int number, char *filename);
+void counter_create(unsigned long number, char *filename);
 
 #endif

+ 1 - 7
counter.c/main.c

@@ -3,16 +3,10 @@
 #include "counter.h"
 
 int main(int argc, char **argv) {
-  int number;
-
   if (argc != 3)
     return 1;
 
-  number = atoi(*argv[1] == '-'? argv[1]+1: argv[1]);
-
-  counter_init();
-
-  counter_create(number, argv[2]);
+  counter_create(strtoul(argv[1], NULL, 10), argv[2]);
 
   counter_release();
 

+ 28 - 0
counter.c/powers_table.h

@@ -0,0 +1,28 @@
+#ifndef _TABLE_H
+#define _TABLE_H
+
+#define POWERS_COUNT 20
+
+static unsigned long powers_table[POWERS_COUNT][2] = {
+  {1UL, 0},
+  {10UL, 1}, 
+  {100UL, 2}, 
+  {1000UL, 3}, 
+  {10000UL, 4}, 
+  {100000UL, 5}, 
+  {1000000UL, 6}, 
+  {10000000UL, 7}, 
+  {100000000UL, 8}, 
+  {1000000000UL, 9}, 
+  {10000000000UL, 10}, 
+  {100000000000UL, 11}, 
+  {1000000000000UL, 12}, 
+  {10000000000000UL, 13}, 
+  {100000000000000UL, 14}, 
+  {1000000000000000UL, 15}, 
+  {10000000000000000UL, 16}, 
+  {100000000000000000UL, 17}, 
+  {1000000000000000000UL, 18}, 
+  {10000000000000000000UL, 19}
+};
+#endif